package com.ybkj.daijia.api.apirest;

import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.ServiceSetting;
import com.ybkj.daijia.serverUtils.ServiceUtil;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.WxSetting;
import com.ybkj.daijia.api.beatpay.utils.BestPayCreateOrder;
import com.ybkj.daijia.api.beatpay.utils.BestPayOrderModel;
import com.ybkj.daijia.api.beatpay.utils.CryptTool;
import com.ybkj.daijia.api.driver.transport.ResultTransport;
import com.ybkj.daijia.api.member.alipay.config.AlipayConfig;
import com.ybkj.daijia.api.member.alipay.sign.MemberOrderSign;
import com.ybkj.daijia.api.member.alipay.sign.RSA;
import com.ybkj.daijia.api.member.alipay.util.AlipayNotify;
import com.ybkj.daijia.api.unionpay.AcpService;
import com.ybkj.daijia.api.unionpay.DemoBase;
import com.ybkj.daijia.api.unionpay.LogUtil;
import com.ybkj.daijia.api.unionpay.SDKConfig;
import com.ybkj.daijia.api.unionpay.SDKConstants;
import com.ybkj.daijia.api.util.ErrorConstantV4;
import com.ybkj.daijia.api.weixin.WeixinUtil;
import com.ybkj.daijia.api.weixin.tenpayv3.Configuration;
import com.ybkj.daijia.api.weixin.tenpayv3.GetWxOrderno;
import com.ybkj.daijia.api.weixin.tenpayv3.RequestHandler;
import com.ybkj.daijia.api.weixin.tenpayv3.Sha1Util;
import com.ybkj.daijia.api.weixin.tenpayv3.TenpayUtil;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.config.ZWYApi;
import com.ybkj.daijia.server.event.model.ActivityCheckEvent;
import com.ybkj.daijia.server.event.model.MemberRebateEvent;
import com.ybkj.daijia.server.event.model.OrderConfirmEvent;
import com.ybkj.daijia.server.event.model.OrderCreateEvent;
import com.ybkj.daijia.server.event.model.OrderFinishEvent;
import com.ybkj.daijia.server.event.model.OrderNewRushEvent;
import com.ybkj.daijia.server.event.model.OrderPassengerHasPayEvent;
import com.ybkj.daijia.server.event.model.OrderRecordEvent;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.mc.PassengerAccount;
import com.ybkj.daijia.server.mc.PassengerGrade;
import com.ybkj.daijia.server.model.Advertisement;
import com.ybkj.daijia.server.model.Area;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.model.Order.OrderCarType;
import com.ybkj.daijia.server.model.Order.OrderCarTypeDetail;
import com.ybkj.daijia.server.model.Order.PayTypeDetails;
import com.ybkj.daijia.server.model.OrderStatus;
import com.ybkj.daijia.server.model.OrderStatus.StatusType;
import com.ybkj.daijia.server.model.OrderTemp;
import com.ybkj.daijia.server.model.PayRecordOrder;
import com.ybkj.daijia.server.model.PayRecordOrder.PayRecordTypeOrder;
import com.ybkj.daijia.server.model.Rate;
import com.ybkj.daijia.server.model.WxBind;
import com.ybkj.daijia.server.reactor.ReactorVo;
import com.ybkj.daijia.server.sales.Activity.ActivityEvent;
import com.ybkj.daijia.server.sales.Activity.OrderType;
import com.ybkj.daijia.server.sales.Coupon;
import com.ybkj.daijia.server.sales.CouponRule;
import com.ybkj.daijia.server.sales.CouponRule.CouponType;
import com.ybkj.daijia.server.service.ActivityService;
import com.ybkj.daijia.server.service.AdvertisementService;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.CarService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.CouponRuleService;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.ErrandService;
import com.ybkj.daijia.server.service.FreightService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderOrbitService;
import com.ybkj.daijia.server.service.OrderService;
import com.ybkj.daijia.server.service.OrderStatusService;
import com.ybkj.daijia.server.service.OrderTempService;
import com.ybkj.daijia.server.service.PayRecordOrderService;
import com.ybkj.daijia.server.service.RateService;
import com.ybkj.daijia.server.service.WxBindService;
import com.ybkj.daijia.server.service.ZhuancheService;
import com.ybkj.daijia.server.service.ZhuanxianService;
import com.ybkj.daijia.server.websocket.WebSocketSend;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller("ApiDaijiaProcessController")
@RequestMapping(value = "api/daijia/")
public class DaijiaProcessController {

    private static final Logger logger = LoggerFactory.getLogger(DaijiaProcessController.class);

    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ErrandService errandService;
    @Autowired
    private ZhuancheService zhuancheService;
    @Autowired
    private ZhuanxianService zhuanxianService;
    @Autowired
    private FreightService freightService;
    @Autowired
    private OrderTempService orderTempService;
    @Autowired
    private CarService carService;
    @Autowired
    private ZhuancheService zhuanService;
    @Autowired
    private OrderStatusService orderStatusService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private RateService rateService;
    @Autowired
    private WxBindService wxBindService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponRuleService couponRuleService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private OrderOrbitService orderOrbitService;
    @Autowired
    private PayRecordOrderService payRecordOrderService;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private AreaService areaService;
    @Autowired
    private AdvertisementService advertisementService;

    @Autowired
    private ZWYApi zWYApi;

    /**
     * 获取请求参数中所有的信息
     *
     * @param request
     * @return
     */
    public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
        Map<String, String> res = new HashMap<String, String>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                // 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                if (null == res.get(en) || "".equals(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }

    @RequestMapping(value = "queryArea")
    public @ResponseBody
    Map<String, Object> queryArea(Long areaId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", false);
        if (null != areaId) {
            Area area = null;
            area = areaService.findOneWithCharge(areaId);
            if (area != null) {
                map.put("data", area);
                map.put("success", true);
            }
        }
        return map;
    }

    @RequestMapping(value = "getEmployStatus")
    public @ResponseBody
    Map<String, Object> getEmployStatus(Long driverId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", false);
        if (null != driverId) {
            Driver driver = driverService.findOne(driverId);
            if (null != driver) {
                map.put("status", driver.getStatus());
                if (null != driver.getJobStatus()) {
                    map.put("jobStatus", driver.getJobStatus());
                } else {
                    map.put("jobStatus", -1);
                }
                map.put("success", true);
            }
        }
        return map;
    }

    @RequestMapping(value = "queryDriver")
    public @ResponseBody
    Map<String, Object> queryDriver(Long driverId) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (null != driverId) {
            Driver driver = driverService.findOne(driverId);
            if (null != driver) {
                Setting setting = settingUtils.get();
                map.put("success", true);
                map.put("employId", driver.getId());
                map.put("employName", driver.getName());
                map.put("employAccount", driver.getUsername());
                map.put("employPhone", driver.getPhone());
                map.put("employScore", driver.getStarLevel());
                map.put("employPhoto", setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                map.put("companyId", driver.getCompanyId());
                Company company = companyService.findOne(driver.getCompanyId());
                map.put("companyName", company.getAbbreviation());
                map.put("employLat", driver.getLastLatitude());
                map.put("employLng", driver.getLastLongitude());
                map.put("errandserviceType", driver.getErrandserviceType());
                map.put("platNo", driver.getPlatNo());
                map.put("status", driver.getStatus());
            } else {
                map.put("success", false);
                map.put("message", "服务人员不存在");
            }
        } else {
            map.put("success", false);
            map.put("message", "服务人员Id不能为空");
        }
        return map;
    }

    // 创建代驾订单
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> create(Long clientId, String clientName, String clientPhone,
        String userPhone, Long serverTime, String startAddress, Double startLat, Double startLng,
        @RequestParam(required = true, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "endAddress") String endAddress,
        @RequestParam(required = false, value = "endLat") Double endLat,
        @RequestParam(required = false, value = "endLng") Double endLng,
        @RequestParam(required = false, value = "fixPriceMoney") BigDecimal fixPriceMoney,
        @RequestParam(required = false, value = "couponId") Long couponId,
        @RequestParam(required = false, value = "fromSource") String fromSource,
        @RequestParam(required = false, value = "orderNoRenBao") String orderNoRenBao,
        @RequestParam(required = false, value = "cuponNoRenBao") String cuponNoRenBao,
        @RequestParam(required = false, value = "preferentialType") String preferentialType) {

        Map<String, Object> map = new HashMap<String, Object>();
        try {
            Setting setting = settingUtils.get();
            boolean prePay = setting.isDaijiaPrePay();
            // 2017/12/25 16:19 张小军过滤微信公众号下单进行预支付
            if (prePay && !StringUtils.isNotBlank(fromSource) && fromSource
                .equals(Order.ORDER_TYPE_WEIXIN)) {
                if (StringUtils.isBlank(endAddress) || null == endLat || null == endLng
                    || null == fixPriceMoney) {
                    map.put("success", false);
                    map.put("code", ErrorConstantV4.PARAM_ERROR.getCode());
                    map.put("message", "代驾订单预付费已开启，预算金额或目的地不能为空");
                    return map;
                }
            }
            Passenger passenger = memberService.findOnePassenger(clientId);
            if (null == passenger) {
                map.put("success", false);
                map.put("code", ErrorConstantV4.PASSENGER_NOT_EXISTS.getCode());
                map.put("message", "客户不存在");
                return map;
            }
            if (passenger.isInBlackList()) {
                map.put("success", false);
                map.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
                map.put("message", "黑名单乘客");
                return map;
            }
            Coupon coupon = null;
            if (null != couponId) {
                coupon = couponService.findOne(couponId);
                if (null == coupon || !coupon.getStatus().equals(Coupon.COUPON_STATUS_NOTUSE)) {
                    map.put("success", false);
                    map.put("code", ErrorConstantV4.COUPON_INVALID.getCode());
                    map.put("message", "优惠劵无效");
                    return map;
                } else {
                    if (!coupon.getCouponRule().getCouponType().equals(CouponType.daijia)) {
                        map.put("success", false);
                        map.put("code", ErrorConstantV4.COUPON_TYPE_ERROR.getCode());
                        map.put("message", "该优惠劵类型不是代驾优惠券");
                        return map;
                    }
                }
            }
            // 并行单量判断
            Long count = orderService.countNotFinishedByPassenger(clientId);
            Long number = 1L;
            if (null != passenger.getGrade_id()) {
                PassengerGrade passengerGrade = memberService.findOneGrade(passenger.getGrade_id());
                if (null != passengerGrade && null != passengerGrade.getParallelOrderNumber()
                    && passengerGrade.getParallelOrderNumber() > 0
                    && count + number > passengerGrade.getParallelOrderNumber()) {
                    map.put("success", false);
                    map.put("code", ErrorConstantV4.ORDER_TOOMACH_ERROR.getCode());
                    map.put("message", "超出最大并行订单数量，不能再下新单。");
                    return map;
                }
            }
            // 如果存在未支付订单，不能下单
            ServiceSetting serviceSetting = ServiceUtil.checkOpen();
            Long notPayAmounts = 0L;
            if (serviceSetting.isDaijia()) {
                notPayAmounts += orderService.countNotPayByPassenger(passenger.getId());
            }
            if (serviceSetting.isPaotui()) {
                notPayAmounts += errandService.countNotPayByPassenger(passenger.getId());
            }
            if (serviceSetting.isZhuanche()) {
                notPayAmounts += zhuancheService.countNotPayByPassenger(passenger.getId());
            }
            if (serviceSetting.isFreight()) {
                notPayAmounts += freightService.countNotPayByPassenger(passenger.getId());
            }
            if (serviceSetting.isZhuanxian()) {
                notPayAmounts += zhuanxianService.countNotPayByPassenger(passenger.getId());
            }
            if (notPayAmounts > 0) {
                map.put("success", false);
                map.put("code", ErrorConstantV4.ORDER_NOTPAY_ERROR.getCode());
                map.put("message", ErrorConstantV4.ORDER_NOTPAY_ERROR.getMessage());
                return map;
            }
            // 今天已经下的（新单、销单、执行中）订单不能超过10单
            Long todayAmounts = orderService.countTodayOrderByPassenger(passenger.getId());
            if (todayAmounts >= 10) {
                map.put("success", false);
                map.put("code", ErrorConstantV4.ORDER_RUNNING_ERROR.getCode());
                map.put("message", ErrorConstantV4.ORDER_RUNNING_ERROR.getMessage());
                return map;
            }
            boolean couponEnough = false;// 优惠券是否已经够支付;
            if (null != coupon) {
                BigDecimal couponMoney = coupon.getCouponRule().getMoney();
                if (null != fixPriceMoney && couponMoney.doubleValue() >= fixPriceMoney
                    .doubleValue()) {
                    couponEnough = true;
                }
            }
            if (StringUtils.isBlank(clientName)) {
                clientName = "先生/女士";
            }
            // 2017/12/25 16:19 张小军过滤微信公众号下单进行预支付
            if (prePay && !couponEnough && StringUtils.isNotBlank(fromSource)
                && !fromSource.equals(Order.ORDER_TYPE_WEIXIN)) {
                OrderTemp orderTemp = new OrderTemp();
                orderTemp.setOrderNoRenBao(orderNoRenBao);
                orderTemp.setCuponNoRenBao(cuponNoRenBao);
                orderTemp.setPreferentialType(preferentialType);
                orderTemp.setClientId(clientId);
                orderTemp.setClientName(clientName);
                orderTemp.setClientPhone(clientPhone);
                orderTemp.setUserPhone(userPhone);
                orderTemp.setFromPlace(startAddress);
                orderTemp.setClientLatitude(startLat);
                orderTemp.setClientLongitude(startLng);
                orderTemp.setToPlace(endAddress);
                orderTemp.setToPlaceLatitude(endLat);
                orderTemp.setToPlaceLongitude(endLng);
                orderTemp.setServerTime(new Date(serverTime));
                orderTemp.setCompanyId(companyId);
                orderTemp.setShouldCash(fixPriceMoney);
                // if(StringUtils.isNotBlank(fromSource) &&
                // fromSource.equals(Order.ORDER_TYPE_XCX)){
                // orderTemp.setFromSource(Order.ORDER_TYPE_XCX);
                // orderTemp.setOrderType(Order.ORDER_TYPE_XCX);
                // }
                // else{
                // orderTemp.setFromSource(Order.ORDER_TYPE_APP);
                // orderTemp.setOrderType(Order.ORDER_TYPE_APP);
                // }
                BigDecimal budgetPay = null;
                if (null != coupon) {
                    orderTemp.setCouponId(coupon.getId());
                    Integer couponType = coupon.getCouponRule().getType();
                    if (couponType.equals(CouponRule.TYPE_DEDUCTION)) {
                        budgetPay = fixPriceMoney.subtract(coupon.getCouponRule().getMoney());
                        orderTemp.setPrepayCash(
                            fixPriceMoney.subtract(coupon.getCouponRule().getMoney()));
                    } else if (couponType.equals(CouponRule.TYPE_DISCOUNT)) {
                        // BigDecimal coupon_hasPayed = (fixPriceMoney.multiply(BigDecimal.valueOf(1 -
                        // (coupon
                        // .getCouponRule().getDiscount() / 10)))).setScale(0, BigDecimal.ROUND_DOWN);
                        // orderTemp.setPrepayCash(fixPriceMoney.subtract(coupon_hasPayed));
                        BigDecimal couponMoney = fixPriceMoney
                            .multiply(
                                BigDecimal.valueOf(1)
                                    .subtract(
                                        BigDecimal.valueOf(coupon.getCouponRule().getDiscount())
                                            .divide(BigDecimal.valueOf(10))))
                            .setScale(0, BigDecimal.ROUND_DOWN);
                        BigDecimal prepayCash = fixPriceMoney.subtract(couponMoney)
                            .setScale(1, BigDecimal.ROUND_DOWN);
                        orderTemp.setPrepayCash(prepayCash);
                        budgetPay = prepayCash;
                    }
                } else {
                    orderTemp.setPrepayCash(fixPriceMoney);
                    budgetPay = fixPriceMoney;
                }
                orderTempService.create(orderTemp);

                map.put("success", true);
                map.put("budgetPay", budgetPay);
                map.put("orderId", orderTemp.getId());
                map.put("prePay", prePay);
                map.put("overdraw", passenger.isAllowOverdraw());
                return map;
            } else {
                Order order = new Order();
                order.setOrderNoRenBao(orderNoRenBao);
                order.setCuponNoRenBao(cuponNoRenBao);
                order.setPreferentialType(preferentialType);
                order.setClientId(clientId);
                order.setClientName(clientName);
                order.setClientPhone(clientPhone);
                order.setUserPhone(userPhone);
                order.setFromPlace(startAddress);
                order.setClientLatitude(startLat);
                order.setClientLongitude(startLng);
                order.setToPlace(endAddress);
                order.setToPlaceLatitude(endLat);
                order.setToPlaceLongitude(endLng);
                order.setServerTime(new Date(serverTime));
                order.setOrderCarType(OrderCarType.daijia);
                order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
                if (StringUtils.isNotBlank(fromSource) && fromSource.equals(Order.ORDER_TYPE_XCX)) {
                    order.setFromSource(Order.ORDER_TYPE_XCX);
                    order.setOrderType(Order.ORDER_TYPE_XCX);
                } else if (StringUtils.isNotBlank(fromSource) && fromSource
                    .equals(Order.ORDER_TYPE_WEIXIN)) {
                    order.setFromSource(Order.ORDER_TYPE_WEIXIN);
                    order.setOrderType(Order.ORDER_TYPE_WEIXIN);
                } else {
                    order.setFromSource(Order.ORDER_TYPE_APP);
                    order.setOrderType(Order.ORDER_TYPE_APP);
                }

                Long[] couponIds = null;
                if (null != coupon) {
                    couponIds = new Long[1];
                    couponIds[0] = coupon.getId();
                }

                Result<Order> result = orderService
                    .create(order, 1, couponIds, startLng, startLat, companyId, null,
                        null, fixPriceMoney);

                if (!result.isSuccess()) {
                    map.put("success", false);
                    map.put("code", ErrorConstantV4.SUCCESS.getCode());
                    map.put("message", result.getMessage());
                    return map;
                }

                for (Order order2 : result.getData()) {
                    OrderCreateEvent event = new OrderCreateEvent(order2);
                    applicationEventMulticaster.multicastEvent(event);

                    OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                    applicationEventMulticaster.multicastEvent(orderRecordEvent);
                }

                OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
                applicationEventMulticaster.multicastEvent(newRushEvent);

                if (!CollectionUtils.isEmpty(result.getData())) {
                    order = result.getData().get(0);
                    map.put("success", true);
                    map.put("orderId", order.getId());
                    if (couponEnough) {
                        map.put("prePay", false);
                    } else {
                        map.put("prePay", prePay);
                    }
                    map.put("overdraw", passenger.isAllowOverdraw());
                    return map;
                } else {
                    map.put("success", false);
                    map.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
                    map.put("message", "代驾订单下单失败");
                    return map;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", ErrorConstantV4.SERVER_ERROR.getCode());
            map.put("success", false);
            map.put("message", "内部服务器错误");
            return map;
        }
    }

    //微信创建订单
    @RequestMapping(value = "createWeixin", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> createWeixin(String ack, String beginAddress,
        @RequestParam(required = false, value = "beginAddressDetail") String beginAddressDetail,
        Double beginLat,
        Double beginLng, @RequestParam(required = false, value = "endAddress") String endAddress,
        @RequestParam(required = false, value = "endAddressDetail") String endAddressDetail,
        @RequestParam(required = false, value = "endLat") Double endLat,
        @RequestParam(required = false, value = "endLng") Double endLng,
        @RequestParam(required = false, value = "money") BigDecimal money, String phone,
        String openId) {

        logger.error(
            "recv ack:{},beginAddress:{},beginAddressDetail:{},beginLat:{},beginLng:{},endAddress:{},endAddressDetail:{},endLat:{},endLng:{},phone:{}",
            ack, beginAddress, beginLat, beginLng, endAddress, endLat, endLng, phone);

        Map<String, Object> map = new HashMap<String, Object>();

        if (StringUtils.isBlank(beginAddress) || null == beginLat || null == beginLng || StringUtils
            .isBlank(phone)) {
            map.put("success", false);
            map.put("message", "参数错误");
            return map;
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);

        if (null == passenger) {
            map.put("success", false);
            map.put("message", "客户不存在，无法下单");
            return map;
        }

        if (passenger.isInBlackList()) {
            map.put("success", false);
            map.put("message", "下单失败");
            return map;
        }

        // 并行单量判断
        Long count = orderService.countNotFinishedByPassenger(passenger.getId());
        Long number = 1L;
        if (null != passenger.getGrade_id()) {
            PassengerGrade passengerGrade = memberService.findOneGrade(passenger.getGrade_id());
            if (null != passengerGrade && null != passengerGrade.getParallelOrderNumber()
                && passengerGrade.getParallelOrderNumber() > 0
                && count + number > passengerGrade.getParallelOrderNumber()) {
                map.put("success", false);
                map.put("code", ErrorConstantV4.ORDER_TOOMACH_ERROR.getCode());
                map.put("message", "超出最大并行订单数量，不能再下新单。");
                return map;
            }
        }

        // 如果存在未支付订单，不能下单
        ServiceSetting serviceSetting = ServiceUtil.checkOpen();
        Long notPayAmounts = 0L;

        if (serviceSetting.isDaijia()) {
            notPayAmounts += orderService.countNotPayByPassenger(passenger.getId());
        }
        if (serviceSetting.isPaotui()) {
            notPayAmounts += errandService.countNotPayByPassenger(passenger.getId());
        }
        if (serviceSetting.isZhuanche()) {
            notPayAmounts += zhuancheService.countNotPayByPassenger(passenger.getId());
        }
        if (serviceSetting.isFreight()) {
            notPayAmounts += freightService.countNotPayByPassenger(passenger.getId());
        }
        if (serviceSetting.isZhuanxian()) {
            notPayAmounts += zhuanxianService.countNotPayByPassenger(passenger.getId());
        }

        if (notPayAmounts > 0) {
            map.put("success", false);
            map.put("code", ErrorConstantV4.ORDER_NOTPAY_ERROR.getCode());
            map.put("message", ErrorConstantV4.ORDER_NOTPAY_ERROR.getMessage());
            return map;
        }

        // 今天已经下的（新单、销单、执行中）订单不能超过10单
        Long todayAmounts = orderService.countTodayOrderByPassenger(passenger.getId());
        if (todayAmounts >= 10) {
            map.put("success", false);
            map.put("code", ErrorConstantV4.ORDER_RUNNING_ERROR.getCode());
            map.put("message", ErrorConstantV4.ORDER_RUNNING_ERROR.getMessage());
            return map;
        }

        Order order = new Order();
        order.setClientId(passenger.getId());
        order.setClientName(passenger.getName());
        order.setClientPhone(passenger.getPhone());
        order.setShouldCash(money);
        order.setFromPlace(beginAddress);
        order.setFromPlaceDetail(beginAddressDetail);
        order.setClientLatitude(beginLat);
        order.setClientLongitude(beginLng);
        order.setToPlace(endAddress);
        order.setToPlaceDetail(endAddressDetail);
        order.setToPlaceLatitude(endLat);
        order.setToPlaceLongitude(endLng);

        order.setServerTime(new Date());
        order.setOrderCarType(OrderCarType.daijia);
        order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);

        Company company = null;
        if (StringUtils.isNotBlank(ack)) {
            Company ackCompany = companyService.findByAppKey(ack);
            if (null != ackCompany) {
                company = ackCompany;
            }
        }
        if (null == company) {
            List<Company> list = companyService
                .findByAreaCityName(HttpClientUtil.getCityByLngAndLat(beginLng, beginLat));
            if (!CollectionUtils.isEmpty(list)) {

                List<Company> notMainCompanys = new ArrayList<Company>();
                Company cityMainCompany = null;

                for (Company c : list) {
                    if (!passenger.getCompanyId().equals(c.getId())) {
                        if (!c.isCompanyType()) {
                            if (StringUtils.isBlank(c.getAppKey())) {
                                notMainCompanys.add(c);
                            }
                        } else {
                            cityMainCompany = c;
                        }
                    } else {
                        company = c;
                        break;
                    }
                }

                if (null == company) {
                    if (!CollectionUtils.isEmpty(notMainCompanys)) {
                        company = notMainCompanys.get(new Random().nextInt(notMainCompanys.size()));
                    }
                }

                if (null == company) {
                    if (null != cityMainCompany) {
                        company = cityMainCompany;
                    }
                }

            }
            if (null == company) {
                company = companyService.getMain();
            }
        }

        order.setCompanyId(company.getId());
        order.setDjxFee(company.getDjxFee());
        order.setYwxFee(company.getYwxFee());

        order = orderService.memberBook(order, openId);

        List<Order> rushOrderList = new ArrayList<Order>();
        rushOrderList.add(order);
        OrderNewRushEvent newRushEvent = new OrderNewRushEvent(rushOrderList);
        applicationEventMulticaster.multicastEvent(newRushEvent);

        if (StringUtils.isNotBlank(openId)) {

            wxBindService.deleteByWxuser(openId);
            wxBindService.deleteByPhone(phone);

            WxBind wxBind = new WxBind();
            wxBind.setCode(null);
            wxBind.setPhone(phone);
            wxBind.setStatus(WxBind.WXBIND_STATUS_SUCCESS);
            wxBind.setWxuser(openId);
            wxBindService.insertRecrod(wxBind);
        }

        map.put("success", true);
        map.put("orderId", order.getId());

        return map;
    }

    // 查询代驾未支付订单
    @RequestMapping(value = "countNotPayAmounts", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> countNotPayAmounts(Long passengerId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            Long notPayAmounts = orderService.countNotPayByPassenger(passengerId);

            map.put("data", notPayAmounts);
            map.put("success", true);
        } catch (Exception e) {
            map.put("success", false);
        }
        return map;
    }

    // 查询代驾未完成订单
    @RequestMapping(value = "findRunning", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findRunning(Long passengerId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            List<Order> list = orderService.findActiveByMember(passengerId);

            map.put("data", list);
            map.put("success", true);
        } catch (Exception e) {
            map.put("success", false);
        }
        return map;
    }

    // 查询代驾未完成订单
    @RequestMapping(value = "findRunningv5", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findRunningv5(Long passengerId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            Map<String, Object> orderMap = new HashMap<String, Object>();
            List<Object> orderList = new ArrayList<Object>();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            List<Order> list = orderService.findActiveByMember(passengerId);

            if (null != list && list.size() > 0) {
                for (Order order : list) {
                    orderMap.put("id", order.getId());
                    orderMap.put("orderNo", order.getOrderNumber());
                    orderMap.put("fromPlace", order.getFromPlace());
                    orderMap.put("clientName", order.getClientName());
                    orderMap.put("clientPhone", order.getClientPhone());
                    orderMap.put("userPhone", order.getUserPhone());
                    orderMap.put("clientId", order.getClientId());
                    orderMap.put("clientLongitude", order.getClientLongitude());
                    orderMap.put("clientLatitude", order.getClientLatitude());
                    orderMap.put("toPlace", order.getToPlace());
                    orderMap.put("toPlaceLongitude", order.getToPlaceLongitude());
                    orderMap.put("toPlaceLatitude", order.getToPlaceLatitude());
                    orderMap.put("serverTime", format.format(order.getServerTime()));
                    orderMap.put("companyId", order.getCompanyId());
                    orderMap.put("treatment", order.isTreatment());
                    orderMap.put("budgetPay", order.getShouldCash());
                    orderMap.put("driverRealName", order.getDriverRealName());
                    orderMap.put("driverStarLevel", order.getDriverStarLevel());
                    orderMap.put("hasbeenRate", order.isHasbeenRate()); // 是否已评价
                    orderMap.put("treatment", order.isTreatment()); // 是否已结算
                    orderMap.put("arrivePlaceDate", order.getArrivePlaceDate()); // 到达预约地时间

                    // 查询订单状态列表
                    List<OrderStatus> orderStatus_ = orderStatusService.findByOrder(order.getId());
                    orderMap.put("orderStatus", orderStatus_); // 订单事件列表

                    // 判断订单状态
                    Long maxId = 0L;
                    for (OrderStatus status : orderStatus_) {
                        // 状态id,最大的id就是最新的订单状态
                        Long statusId = status.getId();
                        if (statusId >= maxId) {
                            maxId = statusId;
                        }
                    }
                    for (OrderStatus status : orderStatus_) {
                        Long statusId = status.getId();
                        if (statusId.equals(maxId) || statusId == maxId) {
                            StatusType type = status.getStatusType();
                            orderMap.put("status", type);
                        }
                    }

                    orderList.add(orderMap);
                }
            }

            map.put("data", orderList);
            map.put("success", true);
        } catch (Exception e) {
            map.put("success", false);
        }
        return map;
    }

    // 代驾订单销单
    @RequestMapping(value = "cancel", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> cancel(Long orderId, String cause) {
        Map<String, Object> map = new HashMap<String, Object>();
        Order order = orderService.findOne(orderId);
        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        } else {
            if (!order.getStatus().equals(Order.ORDER_STATUS_NEW)
                && !order.getStatus().equals(Order.ORDER_STATUS_YIPAIDAN)
                && !order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
                map.put("success", false);
                map.put("message", "开始执行不能销单");
                return map;
            }
            if (order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
                List<OrderStatus> orderStatuss = orderStatusService.findByOrder(order.getId());
                if (!CollectionUtils.isEmpty(orderStatuss)) {
                    Collections.sort(orderStatuss, new Comparator<OrderStatus>() {
                        public int compare(OrderStatus arg0, OrderStatus arg1) {
                            return arg1.getId().compareTo(arg0.getId());
                        }
                    });
                }
                if (orderStatuss.get(0).getStatusType().equals(OrderStatus.StatusType.daijia2)) {
                    map.put("success", false);
                    map.put("message", "开始执行不能销单");
                    return map;
                }
            }
            try {
                orderService.customerCancel(order, cause);
                map.put("success", true);
                map.put("message", "销单成功");

                return map;
            } catch (Exception e) {
                map.put("success", false);
                map.put("message", "销单失败");
                return map;
            }
        }
    }

    // 代驾订单评价
    @RequestMapping(value = "review", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> review(String phone, Long driverId, Long orderId, Double score,
        String content) {
        Map<String, Object> map = new HashMap<String, Object>();
        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            map.put("success", false);
            map.put("message", "客户不存在");
            return map;
        }
        Driver driver = driverService.findOne(driverId);
        if (null == driver) {
            map.put("success", false);
            map.put("message", "服务人员不存在");
            return map;
        }
        Order order = orderService.findOne(orderId);
        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }
        if (!order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
            && !order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            map.put("success", false);
            map.put("message", "订单未完成，无法评价");
            return map;
        }
        Rate oldRate = rateService.findByMemberAndOrder(passenger.getId(), order.getId());
        if (null != oldRate) {
            map.put("success", false);
            map.put("message", "已评价过该订单");
            return map;
        }
        try {
            Rate rate = new Rate();
            rate.setTitle("无");
            rate.setContent(content);
            rate.setDriverId(order.getDriverId());
            rate.setDriverName(order.getDriverName());
            rate.setMemberPhone(phone);
            rate.setMemberId(passenger.getId());
            rate.setOrderId(order.getId());
            rate.setOrderNumber(order.getOrderNumber());
            if (StringUtils.isNotBlank(passenger.getName())) {
                rate.setMemberName(passenger.getName());
            } else {
                rate.setMemberName("先生/女士");
            }
            rate.setStarLevel(score.floatValue());

            rateService.rate(rate, driver, order);

            map.put("success", true);
            map.put("message", "评价成功");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("success", false);
            map.put("message", "内部服务器错误");
        }
        return map;
    }

    /**
     * V5微信获取代驾评价
     *
     * @param passengerId 用户ID
     * @param orderId     订单ID
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getReview", method = {RequestMethod.GET})
    public Map<String, Object> getReviewById(Long passengerId, Long orderId) {
        Map<String, Object> map = new HashMap<String, Object>();
        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            map.put("success", false);
            map.put("message", "客户不存在");
            return map;
        }
        Order order = orderService.findOne(orderId);
        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }
        Rate rate = rateService.findByMemberAndOrder(passengerId, orderId);
        if (null == rate) {
            map.put("success", false);
            map.put("message", "评价不存在");
            return map;
        }
        map.put("success", true);
        map.put("data", rate);
        map.put("message", "请求成功");
        return map;
    }

    // 催单
    @RequestMapping(value = "hurryOrder", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> hurryOrder(Long orderId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            Order order = orderService.findOne(orderId);
            map = orderService.hurryOrder(order.getId());
            Boolean success = (Boolean) map.get("success");
            if (success) {
                Company company = companyService.findOne(order.getCompanyId());
                if (null != company) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("passengerName", order.getClientName());
                    jsonObject.put("orderId", order.getId());
                    jsonObject.put("orderNo", order.getOrderNumber());
                    jsonObject.put("type", "hurryDaijiaOrder_company");

                    jsonObject.put("status", order.getStatus());
                    jsonObject.put("clientName", order.getClientName());
                    jsonObject.put("id", order.getId());
                    jsonObject.put("orderNumber", order.getOrderNumber());

                    Company mainCompany = companyService.getMain();
                    WebSocketSend
                        .boardcastToCompany(jsonObject, company.getId(), mainCompany.getId());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("success", false);
            map.put("message", "内部服务器错误");
        }
        return map;
    }

    // 查询附近服务人员
    @RequestMapping(value = "queryNearDriver", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> queryNearDriver(Double longitude, Double latitude, Double distance) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            // List<Driver> list =
            // driverService.queryNearDrivers(longitude,latitude,Driver.DriverJobType.daijia.toString());
            List<Driver> list = driverService.daijiaListDrivers(longitude, latitude, distance);
            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            Setting setting = settingUtils.get();
            for (Driver driver : list) {
                Map<String, Object> m = new HashMap<String, Object>();
                m.put("driverId", driver.getId());
                m.put("driverName", driver.getName());
                m.put("driverUserName", driver.getUsername());
                m.put("driverHead", setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                m.put("driverStar", driver.getStarLevel());
                m.put("driverTimes", driver.getDriveTimes());
                m.put("driverJialing", driver.getjialing());
                m.put("driverDistance", driver.getDistanceStr());
                m.put("driverMeter", driver.getDistance() * 1000);
                if (driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
                    m.put("driverStatus", 0);
                } else {
                    m.put("driverStatus", 1);
                }
                m.put("driverLng", driver.getLongitude());
                m.put("driverLat", driver.getLatitude());
                mapList.add(m);
            }
            map.put("data", mapList);
            map.put("success", true);
        } catch (Exception e) {
            map.put("success", false);
        }
        return map;
    }

    // 查询单个代驾订单
    @RequestMapping(value = "findOne", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findOne(Long orderId) {
        Map<String, Object> map = new HashMap<String, Object>();

        Order order = orderService.findOne(orderId);

        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        Setting setting = settingUtils.get();

        Map<String, Object> orderMap = new HashMap<String, Object>();
        orderMap.put("id", order.getId());
        orderMap.put("orderNo", order.getOrderNumber());
        orderMap.put("fromPlace", order.getFromPlace());
        orderMap.put("clientName", order.getClientName());
        orderMap.put("clientPhone", order.getClientPhone());
        orderMap.put("userPhone", order.getUserPhone());
        orderMap.put("clientId", order.getClientId());
        orderMap.put("clientLongitude", order.getClientLongitude());
        orderMap.put("clientLatitude", order.getClientLatitude());
        orderMap.put("toPlace", order.getToPlace());
        orderMap.put("toPlaceLongitude", order.getToPlaceLongitude());
        orderMap.put("toPlaceLatitude", order.getToPlaceLatitude());
        orderMap.put("serverTime", format.format(order.getServerTime()));
        orderMap.put("companyId", order.getCompanyId());
        orderMap.put("status", order.getStatus());
        orderMap.put("treatment", order.isTreatment());
        orderMap.put("budgetPay", order.getShouldCash());

        orderMap.put("driverId", order.getDriverId());
        if (null != order.getDriverId()) {
            Driver driver = driverService.findOne(order.getDriverId());
            if (null != driver) {
                orderMap.put("driverName", driver.getName());
                orderMap.put("driverUserName", driver.getUsername());
                orderMap.put("driverPhone", driver.getPhone());
                if (StringUtils.isNotBlank(driver.getPhoto())) {
                    orderMap.put("driverPhoto",
                        setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                } else {
                    orderMap.put("driverPhoto", null);
                }
                orderMap.put("driverScore", driver.getStarLevel());
            }
        }

        Rate rate = rateService.findByMemberAndOrder(order.getClientId(), orderId);
        if (null != rate) {
            map.put("orderScore", rate.getStarLevel());
            map.put("orderContent", rate.getContent());
        }

        if (order.getStatus().equals(Order.ORDER_STATUS_BUSY) || order.getStatus()
            .equals(Order.ORDER_STATUS_FINISHED)
            || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            List<OrderStatus> orderStatuss = orderStatusService.findByOrder(order.getId());
            if (!CollectionUtils.isEmpty(orderStatuss)) {
                Collections.sort(orderStatuss, new Comparator<OrderStatus>() {
                    public int compare(OrderStatus arg0, OrderStatus arg1) {
                        return arg1.getId().compareTo(arg0.getId());
                    }
                });
                List<OrderStatus> nowOrderStatuss = new ArrayList<OrderStatus>();
                for (OrderStatus orderStatus : orderStatuss) {
                    if (orderStatus.getStatusType().equals(OrderStatus.StatusType.accept)) {
                        nowOrderStatuss.add(orderStatus);
                        break;
                    } else {
                        nowOrderStatuss.add(orderStatus);
                    }
                }
                if (!CollectionUtils.isEmpty(nowOrderStatuss)) {
                    for (OrderStatus orderStatus : nowOrderStatuss) {
                        if (orderStatus.getStatusType().equals(OrderStatus.StatusType.accept)) {
                            orderMap.put("acceptTime", format.format(orderStatus.getHappened()));
                        }

                        if (orderStatus.getStatusType().equals(OrderStatus.StatusType.daokehu)) {
                            orderMap.put("arriveTime", format.format(orderStatus.getHappened()));
                        }

                        if (orderStatus.getStatusType().equals(OrderStatus.StatusType.daijia2)) {
                            orderMap
                                .put("startdriveTime", format.format(orderStatus.getHappened()));
                        }

                        if (orderStatus.getStatusType().equals(OrderStatus.StatusType.wancheng)) {
                            orderMap.put("finishTime", format.format(orderStatus.getHappened()));
                        }

                    }
                }
            }
        }

        map.put("success", true);
        map.put("data", orderMap);
        return map;
    }

    /**
     * 微信V5查询单个订单
     *
     * @param orderId 订单ID
     * @return
     */
    @RequestMapping(value = "findOneV5", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findOneV5(Long orderId) {
        Map<String, Object> map = new HashMap<String, Object>();

        Order order = orderService.findOne(orderId);

        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        Setting setting = settingUtils.get();

        Map<String, Object> orderMap = new HashMap<String, Object>();
        orderMap.put("id", order.getId());
        orderMap.put("orderNo", order.getOrderNumber());
        orderMap.put("fromPlace", order.getFromPlace());
        orderMap.put("clientName", order.getClientName());
        orderMap.put("clientPhone", order.getClientPhone());
        orderMap.put("userPhone", order.getUserPhone());
        orderMap.put("clientId", order.getClientId());
        orderMap.put("clientLongitude", order.getClientLongitude());
        orderMap.put("clientLatitude", order.getClientLatitude());
        orderMap.put("toPlace", order.getToPlace());
        orderMap.put("toPlaceLongitude", order.getToPlaceLongitude());
        orderMap.put("toPlaceLatitude", order.getToPlaceLatitude());
        orderMap.put("serverTime", format.format(order.getServerTime()));
        orderMap.put("companyId", order.getCompanyId());
        orderMap.put("treatment", order.isTreatment());
        orderMap.put("budgetPay", order.getShouldCash());

        // 微信V5新增返回
        orderMap.put("driverRealName", order.getDriverRealName());
        orderMap.put("driverStarLevel", order.getDriverStarLevel());
        orderMap.put("hasbeenRate", order.isHasbeenRate()); // 是否已评价
        orderMap.put("treatment", order.isTreatment()); // 是否已结算
        orderMap.put("arrivePlaceDate", order.getArrivePlaceDate()); // 到达预约地时间

        // 查询订单状态列表
        List<OrderStatus> orderStatus_ = orderStatusService.findByOrder(orderId);
        orderMap.put("orderStatus", orderStatus_); // 订单事件列表

        // 判断订单状态
        Long maxId = 0L;
        for (OrderStatus status : orderStatus_) {
            // 状态id,最大的id就是最新的订单状态
            Long statusId = status.getId();
            if (statusId >= maxId) {
                maxId = statusId;
            }
        }
        for (OrderStatus status : orderStatus_) {
            Long statusId = status.getId();
            if (statusId.equals(maxId) || statusId == maxId) {
                StatusType type = status.getStatusType();
                orderMap.put("status", type);
            }
        }

        orderMap.put("driverId", order.getDriverId());
        if (null != order.getDriverId()) {
            Driver driver = driverService.findOne(order.getDriverId());
            if (null != driver) {
                orderMap.put("driverName", driver.getName());
                orderMap.put("driverUserName", driver.getUsername());
                orderMap.put("driverPhone", driver.getPhone());
                orderMap.put("driverStatus", driver.getStatus()); // 司机状态

                // 微信V5新增返回
                orderMap.put("gender", driver.getGender());
                orderMap.put("licenseType", driver.getLicenseType());
                orderMap.put("currentAddress", driver.getCurrentAddress());

                if (StringUtils.isNotBlank(driver.getPhoto())) {
                    orderMap.put("driverPhoto",
                        setting.getWebUrl() + "/upload/driver/" + driver.getPhoto());
                } else {
                    orderMap.put("driverPhoto", null);
                }
                orderMap.put("driverScore", driver.getStarLevel());
            }
        }

        Rate rate = rateService.findByMemberAndOrder(order.getClientId(), orderId);
        if (null != rate) {
            map.put("orderScore", rate.getStarLevel());
            map.put("orderContent", rate.getContent());
        }

        map.put("success", true);
        map.put("data", orderMap);
        return map;
    }

    // 查询订单
    @RequestMapping(value = "findOrders", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findOrders(Long passengerId, Integer page, Integer rows) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", false);
        map.put("message", "查询订单失败");
        Map<String, Object> data = orderService.findByParams(passengerId, page, rows);
        map.put("success", true);
        map.put("data", data);
        map.put("message", "查询代驾订单接口成功");
        return map;
    }

    /**
     * 微信V5查询客户订单
     *
     * @param passengerId 客户ID
     * @param page        页码
     * @param rows        条数
     * @return
     */
    @RequestMapping(value = "findOrdersV5", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> findOrdersV5(Long passengerId, Integer page, Integer rows) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", false);
        map.put("message", "查询订单失败");
        Map<String, Object> data = orderService.findByParamsV5(passengerId, page, rows);
        map.put("success", true);
        map.put("data", data);
        map.put("message", "查询代驾订单接口成功");
        return map;
    }

    // 代驾预算价格
    @RequestMapping(value = "getPrice")
    public @ResponseBody
    Map<String, Object> getPrice(@RequestParam(required = false, value = "ack") String ack,
        @RequestParam(required = false, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "startLat") Double startLat,
        @RequestParam(required = true, value = "startLng") Double startLng,
        @RequestParam(required = false, value = "endLat") Double endLat,
        @RequestParam(required = false, value = "endLng") Double endLng) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            map = orderService.getPrice(ack, passengerId, startLat, startLng, endLat, endLng);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getPrice error : " + e.getMessage());
            map.put("success", false);
            map.put("message", "预算失败");
        }
        return map;
    }

    // 代驾预算价格(根据距离,时间预算)
    @RequestMapping(value = "getNewPrice")
    public @ResponseBody
    Map<String, Object> getNewPrice(@RequestParam(required = false, value = "time") Integer time,
        @RequestParam(required = false, value = "mileage") Double mileage,
        @RequestParam(required = false, value = "ack") String ack,
        @RequestParam(required = false, value = "passengerId") Long passengerId,
        @RequestParam(required = false, value = "startLat") Double startLat,
        @RequestParam(required = false, value = "startLng") Double startLng) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            map = orderService.getNewPrice(ack, passengerId, time, mileage, startLat, startLng);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getNewPrice error : " + e.getMessage());
            map.put("success", false);
            map.put("message", "预算失败");
        }
        return map;
    }

    // 支付宝支付前的接口
    @RequestMapping(value = "alipay/prepay")
    public @ResponseBody
    Map<String, Object> alipayPrepay(HttpServletResponse response, HttpServletRequest request,
        Long orderId) {
        Map<String, Object> mapData = new HashMap<String, Object>();
        try {
            // 这里是查询从临时表查询一个订单信息
            OrderTemp temp = orderTempService.findOne(orderId);
            // 获得setting配置信息
            Setting setting = settingUtils.get();
            // 封装参数
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("PartnerID", setting.getAlipayPartnerID()); // 商户id
            map.put("SellerID", setting.getAlipaySellerID());// 消费者id
            map.put("PartnerPrivKey", setting.getAlipayPartnerPrivKey());// 商户的私钥
            map.put("PartnerPublicKey", AlipayConfig.ali_public_key);// 商户的公钥
            map.put("tradeNO", "daijia_prepay_" + orderId);// 临时表订单Id
            map.put("productName", "代驾预支付");// 代驾预支付
            map.put("productDescription", "代驾预先支付");// 代驾预先支付
            map.put("amount", temp.getPrepayCash());// 预付金额
            map.put("notifyURL", setting.getWebUrl() + "/api/daijia/alipay/notify");// 访问地址
            String content = MemberOrderSign.sign(map); // 将内容封装为待签名的数据
            String sign = RSA.sign(content, setting.getAlipayPartnerPrivKey(), "utf-8"); // 待签名数据
            // ,商户私钥,编码格式
            sign = URLEncoder.encode(sign, "utf-8"); // url后追加中文参数乱码的问题
            String url = content + "&sign=\"" + sign + "\"&sign_type=\"RSA\"";
            mapData.put("success", true);
            mapData.put("url", url); // 最后再把url地址封装好以map形式返回
        } catch (Exception e) {
            logger.error("api daijia prepay 代驾支付 error: {}", e);
            mapData.put("success", false);
            mapData.put("message", "支付接口请求失败");
        }
        return mapData;
    }

    // 支付宝支付后的接口
    @RequestMapping(value = "alipay/notify")
    public synchronized @ResponseBody
    String alipayNotify(HttpServletResponse response, HttpServletRequest request)
        throws UnsupportedEncodingException {
        Setting setting = settingUtils.get(); // 首先还是获得设置信息
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap(); // 获得支付宝封装的map的参数，下面进行迭代
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            // 获得所有参数的名称
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            // 循环遍历所有支付宝封装的数据参数 运用三元运算符，再put进去
            for (int i = 0; i < values.length; i++) {
                valueStr =
                    (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }

            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        // 商户订单号
        String out_trade_no = new String(
            request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        // 支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 交易状态
        String trade_status = new String(
            request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        logger.error("商户订单号：" + out_trade_no);
        logger.error("交易号：" + trade_no + "交易状态：" + trade_status);
        if (AlipayNotify.verify(params, setting)) {// 验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                OrderTemp temp = orderTempService.findOne(orderId); // 查找到代驾临时订单
                if (temp.isTreatment()) { // 预支付是否成功付款
                    return "success";
                }

                Order order = new Order();
                if (null != temp.getOrderNoRenBao() && null != temp.getCuponNoRenBao()) {
                    order.setOrderNoRenBao(temp.getOrderNoRenBao());
                    order.setCuponNoRenBao(temp.getCuponNoRenBao());
                }
                order.setClientId(temp.getClientId());
                order.setClientName(temp.getClientName());
                order.setClientPhone(temp.getClientPhone());
                order.setUserPhone(temp.getUserPhone());
                order.setFromPlace(temp.getFromPlace());
                order.setClientLatitude(temp.getClientLatitude());
                order.setClientLongitude(temp.getClientLongitude());
                order.setToPlace(temp.getToPlace());
                order.setToPlaceLatitude(temp.getToPlaceLatitude());
                order.setToPlaceLongitude(temp.getToPlaceLongitude());
                order.setServerTime(temp.getServerTime());
                order.setOrderCarType(OrderCarType.daijia);
                order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
                order.setAlipayMoney(temp.getPrepayCash());
                order.setFromSource(Order.ORDER_TYPE_APP);
                order.setOrderType(Order.ORDER_TYPE_APP);
                // 客户所持优惠券
                Coupon coupon = null;
                if (null != temp.getCouponId()) {
                    coupon = couponService.findOne(temp.getCouponId());
                }
                // 预支付方式
                if (null != coupon) {
                    order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_alipay); // 直接执行
                    // 优惠券+支付宝
                } else {
                    order.setPrePayTypeDetail(Order.PayTypeDetails.alipay); // 直接执行支付宝
                }
                // 如果预支付方式不为空的话，直接获得预支付的id
                Long[] couponIds = null;
                if (null != coupon) {
                    couponIds = new Long[1];
                    couponIds[0] = coupon.getId();
                }
                // 创建订单结果
                Result<Order> result = orderService
                    .create(order, 1, couponIds, temp.getClientLongitude(),
                        temp.getClientLatitude(), temp.getCompanyId(), null, null,
                        temp.getShouldCash());

                if (!result.isSuccess()) {
                    return "fail";
                }

                // 更新为交易成功
                orderTempService.updateTreatment(temp.getId());

                // 客户消费记录
                Order newOrder = result.getData().get(0);
                // 查询乘客
                Passenger passenger = memberService.findOnePassenger(temp.getClientId());
                // 进行订单数据费用拼接
                String payMemo = "订单【" + newOrder.getOrderNumber() + "】预付费使用支付宝支付"
                    + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";
                // 如果优惠券不为空
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
                    }
                }
                // 判断如果乘客是个人的话
                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    memberService.money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                        PassengerAccount.OPERATING_SYS, PassengerAccount.PayType.PAYTYPE_ALIPAY,
                        newOrder.getId(),
                        newOrder.getOrderNumber(), PassengerAccount.ORDER_TYPE_DAIJIA, null, false,
                        false);
                }

                // 判断如果乘客是企业的话
                else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    if (null != enterprise) {
                        memberService
                            .moneyEnterprise(enterprise, temp.getPrepayCash().negate(), payMemo,
                                PassengerAccount.OPERATING_SYS,
                                PassengerAccount.PayType.PAYTYPE_ALIPAY,
                                newOrder.getId(), newOrder.getOrderNumber(),
                                PassengerAccount.ORDER_TYPE_DAIJIA, null,
                                false, false);
                    }
                }

                for (Order order2 : result.getData()) {
                    OrderCreateEvent event = new OrderCreateEvent(order2);
                    applicationEventMulticaster.multicastEvent(event);

                    OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                    applicationEventMulticaster.multicastEvent(orderRecordEvent);
                }

                OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
                applicationEventMulticaster.multicastEvent(newRushEvent);

                return "success";

            } else if (trade_status.equals("TRADE_SUCCESS")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                OrderTemp temp = orderTempService.findOne(orderId);
                if (temp.isTreatment()) {
                    return "success";
                }

                Order order = new Order();
                if (null != temp.getOrderNoRenBao() && null != temp.getCuponNoRenBao()) {
                    order.setOrderNoRenBao(temp.getOrderNoRenBao());
                    order.setCuponNoRenBao(temp.getCuponNoRenBao());
                }
                order.setClientId(temp.getClientId());
                order.setClientName(temp.getClientName());
                order.setClientPhone(temp.getClientPhone());
                order.setUserPhone(temp.getUserPhone());
                order.setFromPlace(temp.getFromPlace());
                order.setClientLatitude(temp.getClientLatitude());
                order.setClientLongitude(temp.getClientLongitude());
                order.setToPlace(temp.getToPlace());
                order.setToPlaceLatitude(temp.getToPlaceLatitude());
                order.setToPlaceLongitude(temp.getToPlaceLongitude());
                order.setServerTime(temp.getServerTime());
                order.setOrderCarType(OrderCarType.daijia);
                order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
                order.setAlipayMoney(temp.getPrepayCash());
                order.setFromSource(Order.ORDER_TYPE_APP);
                order.setOrderType(Order.ORDER_TYPE_APP);

                Coupon coupon = null;
                if (null != temp.getCouponId()) {
                    coupon = couponService.findOne(temp.getCouponId());
                }

                if (null != coupon) {
                    order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_alipay);
                } else {
                    order.setPrePayTypeDetail(Order.PayTypeDetails.alipay);
                }

                Long[] couponIds = null;
                if (null != coupon) {
                    couponIds = new Long[1];
                    couponIds[0] = coupon.getId();
                }

                Result<Order> result = orderService
                    .create(order, 1, couponIds, temp.getClientLongitude(),
                        temp.getClientLatitude(), temp.getCompanyId(), null, null,
                        temp.getShouldCash());
                if (!result.isSuccess()) {
                    return "fail";
                }

                orderTempService.updateTreatment(temp.getId());

                // 客户消费记录
                Order newOrder = result.getData().get(0);
                // 查询出该乘客信息
                Passenger passenger = memberService.findOnePassenger(temp.getClientId());

                String payMemo = "订单【" + newOrder.getOrderNumber() + "】预付费使用支付宝支付"
                    + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";

                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
                    }
                }

                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    memberService.money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                        PassengerAccount.OPERATING_SYS, PassengerAccount.PayType.PAYTYPE_ALIPAY,
                        newOrder.getId(),
                        newOrder.getOrderNumber(), PassengerAccount.ORDER_TYPE_DAIJIA, null, false,
                        false);
                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    if (null != enterprise) {
                        memberService
                            .moneyEnterprise(enterprise, temp.getPrepayCash().negate(), payMemo,
                                PassengerAccount.OPERATING_SYS,
                                PassengerAccount.PayType.PAYTYPE_ALIPAY,
                                newOrder.getId(), newOrder.getOrderNumber(),
                                PassengerAccount.ORDER_TYPE_DAIJIA, null,
                                false, false);
                    }
                }

                for (Order order2 : result.getData()) {
                    OrderCreateEvent event = new OrderCreateEvent(order2);
                    applicationEventMulticaster.multicastEvent(event);

                    OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                    applicationEventMulticaster.multicastEvent(orderRecordEvent);
                }

                OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
                applicationEventMulticaster.multicastEvent(newRushEvent);

                return "success";
            }

            return "fail";
        } else {
            return "fail";
        }

    }

    // 微信支付前接口
    @RequestMapping(value = "wx/prepay")
    public synchronized @ResponseBody
    SortedMap<String, String> wxPrepay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {

        // 查询出代驾的订单
        OrderTemp temp = orderTempService.findOne(orderId);
        // 获得设置
        Setting setting = settingUtils.get();
        // 生成创建订单的URL定制
        String createOrderURL = Configuration.createOrderURL;

        // 商户相关资料
        String appid = setting.getWxAppID();
        String appsecret = setting.getWxAppSecret();
        String partner = setting.getWxPartnerID();
        String partnerkey = setting.getWxPartnerKey();

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "下单付费";
        // 商户订单号
        String out_trade_no = "daijia_prepay_" + orderId;
        // 总金额以分为单位，不带小数点
        String total_fee = String
            .valueOf(temp.getPrepayCash().multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = setting.getWebUrl() + "/api/daijia/wx/notify";

        String trade_type = "APP";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>"
            + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + body
            + "]]></body>"
            + "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
            // "<total_fee>"+1+"</total_fee>"+
            "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip
            + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>"
            + trade_type
            + "</trade_type>" + "</xml>";

        String prepay_id = "";
        try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                logger.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appid", appid);
        finalpackage.put("partnerid", partner);
        finalpackage.put("prepayid", prepay_id);
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("noncestr", nonce_str);
        finalpackage.put("timestamp", timestamp);
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("sign", finalsign); // 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。

        finalpackage.put("success", Boolean.TRUE.toString());

        return finalpackage;

    }

    // 微信支付后接口
    @RequestMapping("wx/notify")
    public synchronized @ResponseBody
    String wxNotify(HttpServletResponse response, HttpServletRequest request)
        throws Exception {

        String out_trade_no = "";

        try {
            // BufferedReader 为带有默认缓冲的字符输出输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            String strxml = sb.toString();
            // 字节输入流
            InputStream in = new ByteArrayInputStream(strxml.getBytes());
            // 在java中可以使用saxbuilder来操作xml格式文件,
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                if (k.equals("out_trade_no")) {
                    out_trade_no = e.getText();
                }
            }
            // 以上主要就是解析XML的
            try {
                // 关闭流
                if (null != in) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 做权限判断
            if (StringUtils.isBlank(out_trade_no)) {
                return "FAIL";
            }
            // 商户订单号 取数组下表第三位：2
            Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
            // 临时订单
            OrderTemp temp = orderTempService.findOne(orderId);
            // 判断预支付是否成功付款
            if (temp.isTreatment()) {
                return "SUCCESS";
            }
            // 将订单相关信息set进去
            Order order = new Order();
            if (null != temp.getOrderNoRenBao() && null != temp.getCuponNoRenBao()) {
                order.setOrderNoRenBao(temp.getOrderNoRenBao());
                order.setCuponNoRenBao(temp.getCuponNoRenBao());
            }
            order.setClientId(temp.getClientId());
            order.setClientName(temp.getClientName());
            order.setClientPhone(temp.getClientPhone());
            order.setUserPhone(temp.getUserPhone());
            order.setFromPlace(temp.getFromPlace());
            order.setClientLatitude(temp.getClientLatitude());
            order.setClientLongitude(temp.getClientLongitude());
            order.setToPlace(temp.getToPlace());
            order.setToPlaceLatitude(temp.getToPlaceLatitude());
            order.setToPlaceLongitude(temp.getToPlaceLongitude());
            order.setServerTime(temp.getServerTime());
            order.setOrderCarType(OrderCarType.daijia);
            order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
            order.setWeixinMoney(temp.getPrepayCash());
            order.setFromSource(Order.ORDER_TYPE_APP);
            order.setOrderType(Order.ORDER_TYPE_APP);
            // 判断优惠券不为空的话，查询到当前优惠券的id
            Coupon coupon = null;
            if (null != temp.getCouponId()) {
                coupon = couponService.findOne(temp.getCouponId());
            }
            /**
             * 优惠劵+微信
             */
            if (null != coupon) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_weixin);
            }
            // 微信
            else {
                order.setPrePayTypeDetail(Order.PayTypeDetails.weixin);
            }

            Long[] couponIds = null;
            if (null != coupon) {
                couponIds = new Long[1];
                couponIds[0] = coupon.getId();
            }
            // 创建订单
            Result<Order> result = orderService
                .create(order, 1, couponIds, temp.getClientLongitude(),
                    temp.getClientLatitude(), temp.getCompanyId(), null, null,
                    temp.getShouldCash());

            if (!result.isSuccess()) {
                return "FAIL";
            }

            // 更新为交易成功
            orderTempService.updateTreatment(temp.getId());

            // 客户消费记录
            Order newOrder = result.getData().get(0);

            // 乘客
            Passenger passenger = memberService.findOnePassenger(temp.getClientId());
            // 拼接乘客需要支付的数据
            String payMemo = "订单【" + newOrder.getOrderNumber() + "】预付费使用微信支付"
                + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";
            // 这里是判断如果有优惠券的话，则在支付的数据后面进行拼接 优惠券分为多少元或者打几折的
            if (null != coupon) {
                if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                    payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";
                } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                    payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
                }
            }
            // 判断是个人还是企业，这里是个人
            if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                memberService.money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                    PassengerAccount.OPERATING_SYS, PassengerAccount.PayType.PAYTYPE_WEIXIN,
                    newOrder.getId(),
                    newOrder.getOrderNumber(), PassengerAccount.ORDER_TYPE_DAIJIA, null, false,
                    false);
            }
            // 否则如果乘客是企业的话
            else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                // 先根据id查询出企业
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                if (null != enterprise) {
                    // 判断如果企业不为空的话，查询企业支付费用
                    memberService
                        .moneyEnterprise(enterprise, temp.getPrepayCash().negate(), payMemo,
                            PassengerAccount.OPERATING_SYS, PassengerAccount.PayType.PAYTYPE_WEIXIN,
                            newOrder.getId(),
                            newOrder.getOrderNumber(), PassengerAccount.ORDER_TYPE_DAIJIA, null,
                            false, false);
                }
            }

            // 这里做订单遍历
            for (Order order2 : result.getData()) {

                // 创建订单对象
                OrderCreateEvent event = new OrderCreateEvent(order2);
                // 事件广播器：ApplicationEventMulticaster，将Springpublish的事件广播给所有的监听器。
                applicationEventMulticaster.multicastEvent(event);

                OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                applicationEventMulticaster.multicastEvent(orderRecordEvent);
            }

            OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
            applicationEventMulticaster.multicastEvent(newRushEvent);

            return "SUCCESS";
        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }

    }

    // 余额签单支付
    @RequestMapping(value = "balancesignPay", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> balancesignPay(Long orderId, Long passengerId, String payType) {

        Map<String, Object> map = new HashMap<String, Object>();

        if (!"balance".equals(payType) && !"sign".equals(payType)) {
            map.put("success", false);
            map.put("message", "支付方式不正确");
            return map;
        }

        OrderTemp temp = orderTempService.findOne(orderId);
        if (null == temp) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }

        if (temp.isTreatment()) {
            map.put("success", false);
            map.put("message", "订单已付费");
            return map;
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            map.put("success", false);
            map.put("message", "当前客户不存在");
            return map;
        }

        if ("sign".equals(payType)) {
            if (!passenger.isAllowOverdraw()) {
                map.put("success", false);
                map.put("message", "当前客户不能签单");
                return map;
            }
        }
        // 个人用户
        else if ("balance".equals(payType)) {
            if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                if (passenger.getDrawMoney().add(passenger.getNodrawMoney()).doubleValue() < temp
                    .getPrepayCash()
                    .doubleValue()) {
                    map.put("success", false);
                    map.put("message", "当前客户余额不足");
                    return map;
                }
            }
            // 企业用户
            else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                if (enterprise.getDrawMoney().add(enterprise.getNodrawMoney()).doubleValue() < temp
                    .getPrepayCash()
                    .doubleValue()) {
                    map.put("success", false);
                    map.put("message", "当前客户余额不足");
                    return map;
                }
            }
        }
        // 创建新的订单
        Order order = new Order();
        order.setClientId(temp.getClientId());
        order.setClientName(temp.getClientName());
        order.setClientPhone(temp.getClientPhone());
        order.setUserPhone(temp.getUserPhone());
        order.setFromPlace(temp.getFromPlace());
        order.setClientLatitude(temp.getClientLatitude());
        order.setClientLongitude(temp.getClientLongitude());
        order.setToPlace(temp.getToPlace());
        order.setToPlaceLatitude(temp.getToPlaceLatitude());
        order.setToPlaceLongitude(temp.getToPlaceLongitude());
        order.setServerTime(temp.getServerTime());
        order.setOrderCarType(OrderCarType.daijia);
        order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
        order.setFromSource(Order.ORDER_TYPE_APP);
        order.setOrderType(Order.ORDER_TYPE_APP);

        if ("sign".equals(payType)) {
            order.setSignMoney(temp.getPrepayCash());
        } else if ("balance".equals(payType)) {
            order.setBalanceMoney(temp.getPrepayCash());
        }

        Coupon coupon = null;
        if (null != temp.getCouponId()) {
            coupon = couponService.findOne(temp.getCouponId());
        }
        /**
         * 优惠劵+签单
         */
        if (null != coupon) {
            if ("sign".equals(payType)) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_sign);
            }
            /**
             * 优惠劵+余额
             */
            else if ("balance".equals(payType)) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_balance);
            }
        }
        // 签单
        else {
            if ("sign".equals(payType)) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.sign);
            }
            // 余额
            else if ("balance".equals(payType)) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.balance);
            }
        }

        Long[] couponIds = null;
        if (null != coupon) {
            couponIds = new Long[1];
            couponIds[0] = coupon.getId();
        }

        Result<Order> result = orderService.create(order, 1, couponIds, temp.getClientLongitude(),
            temp.getClientLatitude(), temp.getCompanyId(), null, null, temp.getShouldCash());

        if (!result.isSuccess()) {
            map.put("success", false);
            map.put("message", result.getMessage());
            return map;
        }

        // 更新为交易成功
        orderTempService.updateTreatment(temp.getId());

        // 客户减钱，客户消费记录
        Order newOrder = result.getData().get(0);

        PassengerAccount.PayType ptype = null;

        String payMemo = "";

        if ("sign".equals(payType)) {
            ptype = PassengerAccount.PayType.PAYTYPE_SIGN;
            payMemo += "订单【" + newOrder.getOrderNumber() + "】预付费使用签单支付"
                + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";
        } else if ("balance".equals(payType)) {
            ptype = PassengerAccount.PayType.PAYTYPE_BALANCE;
            payMemo += "订单【" + newOrder.getOrderNumber() + "】预付费使用余额支付"
                + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";
        }

        if (null != coupon) {
            if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";
            } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
            }
        }

        if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
            memberService.money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                PassengerAccount.OPERATING_SYS,
                ptype, newOrder.getId(), newOrder.getOrderNumber(),
                PassengerAccount.ORDER_TYPE_DAIJIA, null, true,
                true);
        } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
            Enterprise enterprise = memberService.findOneEnterprise(passenger.getEnterprise_id());
            if (null != enterprise) {
                memberService.moneyEnterprise(enterprise, temp.getPrepayCash().negate(), payMemo,
                    PassengerAccount.OPERATING_SYS, ptype, newOrder.getId(),
                    newOrder.getOrderNumber(),
                    PassengerAccount.ORDER_TYPE_DAIJIA, null, true, true);
            }
        }

        for (Order order2 : result.getData()) {
            OrderCreateEvent event = new OrderCreateEvent(order2);
            applicationEventMulticaster.multicastEvent(event);

            OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
            applicationEventMulticaster.multicastEvent(orderRecordEvent);
        }

        OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
        applicationEventMulticaster.multicastEvent(newRushEvent);

        map.put("success", true);
        return map;

    }

    /***
     * 查询有效优惠券
     * @param passengerId
     * @return
     */
    @RequestMapping(value = "listValidCouponsByPassenger", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> listValidCouponsByPassenger(Long passengerId) {

        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> couponMapList = new ArrayList<Map<String, Object>>();

        List<Coupon> coupons = couponService
            .listByPassenger(passengerId, CouponType.daijia, null, null);
        if (!CollectionUtils.isEmpty(coupons)) {
            for (Coupon coupon : coupons) {
                CouponRule rule = coupon.getCouponRule();
                Map<String, Object> couponMap = new HashMap<String, Object>();
                couponMap.put("couponId", coupon.getId());
                couponMap.put("couponType", rule.getType());
                couponMap.put("couponMoney", rule.getMoney());
                couponMap.put("couponDiscount", rule.getDiscount());
                couponMap.put("couponCode", coupon.getCode());
                couponMap.put("couponTitle", rule.getTitle());
                couponMap.put("startTime", rule.getStart().getTime());
                if (null != rule.getEnd()) {
                    couponMap.put("endTime", rule.getEnd().getTime());
                } else {
                    couponMap.put("endTime", null);
                }
                couponMapList.add(couponMap);
            }
        }

        map.put("code", 0);
        map.put("data", couponMapList);
        map.put("msg", "成功");
        return map;
    }

    /****
     * 完成任务数据??
     * @param orderId
     * @return
     */
    @RequestMapping(value = "completeTaskData", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> completeTaskData(Long orderId) {

        logger.error("recv orderId:{}", orderId);

        Map<String, Object> map = new HashMap<String, Object>();

        Order order = orderService.findOne(orderId);

        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            map.put("success", false);
            map.put("message", "订单状态不正确");
            return map;
        }

        Driver driver = driverService.findOne(order.getDriverId());
        if (null == driver) {
            map.put("success", false);
            map.put("message", "订单服务人员不存在");
            return map;
        }

        Passenger passenger = memberService.findOnePassenger(order.getClientId());
        if (null == passenger) {
            map.put("success", false);
            map.put("message", "订单客户不存在");
            return map;
        }

        try {
            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNumber());
            map.put("orderType", "daijia");

            map.put("passengerPhone", passenger.getPhone());
            map.put("passengerName", passenger.getName());
            map.put("passengerType", passenger.getTypeStr());

            // 等级
            map.put("passengerGrade", passenger.getGrade_name());

            Company orderCompany = companyService.findOne(order.getCompanyId());
            map.put("orderCompanyName", orderCompany.getAbbreviation());

            Company passengerCompany = companyService.findOne(passenger.getCompanyId());
            map.put("passengerCompanyName", passengerCompany.getAbbreviation());

            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put("overdraw", passenger.isAllowOverdraw());
                map.put("virtual",
                    passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put("overdraw", enterprise.isAllowOverdraw());
                map.put("virtual",
                    enterprise.getDrawMoney().add(enterprise.getNodrawMoney()).setScale(2,
                        BigDecimal.ROUND_HALF_UP));
            }

            // 优惠券
            if (null != order.getCouponId()) {
                Coupon coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    CouponRule couponRule = coupon.getCouponRule();
                    if (couponRule.getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        map.put("couponMoney", couponRule.getMoney());
                    } else if (couponRule.getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        map.put("discount", couponRule.getDiscount());
                    }
                }
            }

            // 预先支付
            BigDecimal preyMoney = BigDecimal.ZERO;
            if (null != order.getAlipayMoney() && order.getAlipayMoney().doubleValue() > 0) {
                preyMoney = order.getAlipayMoney();
            } else if (null != order.getWeixinMoney() && order.getWeixinMoney().doubleValue() > 0) {
                preyMoney = order.getWeixinMoney();
            } else if (null != order.getSignMoney() && order.getSignMoney().doubleValue() > 0) {
                preyMoney = order.getSignMoney();
            } else if (null != order.getBalanceMoney()
                && order.getBalanceMoney().doubleValue() > 0) {
                preyMoney = order.getBalanceMoney();
            }
            map.put("preyMoney", preyMoney.setScale(2, BigDecimal.ROUND_HALF_UP));

            map.put("employId", driver.getId());
            map.put("employName", driver.getName());
            map.put("employPhone", driver.getPhone());

            map.put("success", true);
            return map;

        } catch (Exception e) {
            e.printStackTrace();
            map.put("success", false);
            map.put("message", "内部服务器错误");
            return map;
        }

    }

    /***
     * 检查任务
     * @param orderId
     * @return
     */
    @RequestMapping(value = "checkTask", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> checkTask(Long orderId) {

        Map<String, Object> map = new HashMap<String, Object>();

        Order order = orderService.findOne(orderId);
        if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            map.put("finished", true);
        } else {
            map.put("finished", false);
        }

        map.put("success", true);
        return map;

    }

    /**
     * 确认任务
     *
     * @param orderId
     * @param realCash
     * @param guoluMoney
     * @param yuanchengMoney
     * @param otherMoney
     * @param mileage
     * @param waitedTime
     * @param travelTime
     * @param toPlace
     * @param toPlaceLng
     * @param toPlaceLat
     * @param startPrice
     * @param mileagePrice
     * @param runTimePrice
     * @param waitPrice
     * @param memo
     * @param xml
     * @return
     */
    @RequestMapping(value = "confirmTask", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> confirmTask(Long orderId, BigDecimal realCash, BigDecimal guoluMoney,
        BigDecimal yuanchengMoney, BigDecimal otherMoney, Double mileage, Integer waitedTime,
        Integer travelTime,
        @RequestParam(required = false, value = "toPlace") String toPlace,
        @RequestParam(required = false, value = "toPlaceLng") Double toPlaceLng,
        @RequestParam(required = false, value = "toPlaceLat") Double toPlaceLat,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "xml") String xml) {

        // realCash应为app计算出的金额 不包含优惠券

        logger.error(
            "recv orderId:{}," + "realCash:{},guoluMoney:{},yuanchengMoney:{},otherMoney:{},"
                + "mileage:{},waitedTime:{},travelTime:{},"
                + "toPlace:{},toPlaceLng:{},toPlaceLat:{},"
                + "startPrice:{},mileagePrice:{},runTimePrice:{},waitPrice:{},xml:{}",
            orderId, realCash, guoluMoney, yuanchengMoney, otherMoney, mileage, waitedTime,
            travelTime, toPlace,
            toPlaceLng, toPlaceLat, startPrice, mileagePrice, runTimePrice, waitPrice, xml);

        Map<String, Object> map = new HashMap<String, Object>();

        if (null == orderId || null == realCash || null == mileage || null == waitedTime
            || null == travelTime) {
            map.put("success", false);
            map.put("message", "参数错误");
            return map;
        }

        Order order = orderService.findOne(orderId);

        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            map.put("success", false);
            map.put("message", "订单状态不正确");
            return map;
        }

        if (order.isTreatment()) {
            map.put("success", true);
            map.put("type", "waitfinish");
            return map;
            // map.put("success", false);
            // map.put("message","订单已确认");
            // return map;
        }

        try {
            BigDecimal hasPayed = BigDecimal.ZERO;// 之前已经实际支付的钱

            hasPayed = hasPayed.add(order.getSignMoney());

            hasPayed = hasPayed.add(order.getBalanceMoney());

            hasPayed = hasPayed.add(order.getAlipayMoney());

            hasPayed = hasPayed.add(order.getWeixinMoney());

            order.setGuoluMoney(guoluMoney);
            order.setYuanchengMoney(yuanchengMoney);
            order.setOtherMoney(otherMoney);
            order.setRealCash(realCash);
            // 优惠券
            Coupon coupon = null;
            BigDecimal coupon_hasPayed = BigDecimal.ZERO;
            Double discount = null;
            if (null != order.getCouponId()) {
                coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
//                        coupon_hasPayed = coupon.getCouponRule().getMoney();
                        coupon_hasPayed = coupon.getCouponPrice();
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
//                        discount = coupon.getCouponRule().getDiscount();
                        discount = coupon.getCouponDiscount();
                        coupon_hasPayed = (realCash.subtract(order.getGuoluMoney())
                            .multiply(new BigDecimal(1 - (discount / 10))))
                            .setScale(0, BigDecimal.ROUND_DOWN);
                    }
                }
            }

            order.setCouponMoney(coupon_hasPayed);
            if (coupon_hasPayed.doubleValue() > 0 && null == order.getPrePayTypeDetail()) {
                order.setPrePayTypeDetail(Order.PayTypeDetails.coupon);
            }
            order.setDiscount(discount);

            BigDecimal m = new BigDecimal(mileage);
            double df = m.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            order.setMileage(df);

            order.setWaitedTime(waitedTime);
            order.setTravelTime(travelTime);

            order.setStartPrice(startPrice);
            order.setMileagePrice(mileagePrice);
            order.setTravelPrice(runTimePrice);
            order.setWaitedPrice(waitPrice);

            if (StringUtils.isNotBlank(toPlace) && null != toPlaceLng && null != toPlaceLat) {
                if (StringUtils.isBlank(order.getToPlace())) {
                    order.setToPlaceLongitude(toPlaceLng);
                    order.setToPlaceLatitude(toPlaceLat);
                    order.setToPlace(toPlace);
                }
            }

            order.setTreatment(true);
            if (StringUtils.isNotBlank(memo)) {
                order.setCarNumber(memo);
            }

            // 确认并报单
            orderService.reportV3(order, xml);

            Passenger passenger = memberService.findOnePassenger(order.getClientId());
            passenger.setPlateNumber(memo);
            memberService.updatePassenger(passenger);

            BigDecimal money = order.getRealCash();// 还需支付的钱
            money = money.subtract(order.getGuoluMoney());
            money = money.subtract(coupon_hasPayed);
            if (money.doubleValue() < 0) {
                money = BigDecimal.ZERO;
            }
            money = money.subtract(hasPayed);
            money = money.add(order.getGuoluMoney());
            // 0898JHDJ3 全额抵扣
            if (money.doubleValue() <= 0
                || (null != order.getPreferentialType() && order.getPreferentialType()
                .equals("0898JHDJ3"))) {
                Driver driver = driverService.findOne(order.getDriverId());
                // 直接结算
                Result<Order> result = null;
                // 醉无忧 - 人保新加
                if (null != order.getOrderNoRenBao() && null != order.getCuponNoRenBao()) {
                    result = orderService
                        .completeTaskNewV3(order, passenger, driver, "renBaoPay", null, hasPayed,
                            false);
                } else {
                    // 直接结算
                    result = orderService
                        .completeTaskNewV3(order, passenger, driver, "clickComplete", null,
                            hasPayed,
                            false);
                }
                if (result.isSuccess()) {
                    // 完成工单事件
                    ReactorVo rVo = new ReactorVo();
                    rVo.setDriver(driver);
                    rVo.setOrder(order);
                    OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                    applicationEventMulticaster.multicastEvent(finishEvent);
                    if (null != passenger) {
                        ReactorVo rVo2 = new ReactorVo();
                        rVo2.setOrderChannelName(order.getOrderType());
                        rVo2.setOrderType(OrderType.daijia);
                        rVo2.setPassenger(passenger);
                        rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                        ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                        applicationEventMulticaster.multicastEvent(activityCheckEvent);

                        MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger,
                            order,
                            order.getRealCash(), 1);
                        applicationEventMulticaster.multicastEvent(memberRebateEvent);
                    }
                    map.put("success", true);
                    map.put("type", "hasfinished");
                    return map;
                } else {
                    map.put("success", false);
                    map.put("message", result.getMessage());
                    return map;
                }
            } else {
                // 进入确认页面
                // 醉无忧 - 人保新加
                if (null != order.getOrderNoRenBao() && null != order.getCuponNoRenBao()) {
                    if (null != order.getOrderNoRenBao() && null != order.getCuponNoRenBao()) {
                        if (null != order.getPreferentialType()) {
                            // 0898JHDJ1 == 38 0898JHDJ2 == 58 抵扣的金额
                            if (order.getPreferentialType().equals("0898JHDJ1")) {
                                realCash = realCash.subtract(new BigDecimal(38));
                            } else if (order.getPreferentialType().equals("0898JHDJ2")) {
                                realCash = realCash.subtract(new BigDecimal(58));
                            }
                        }
                    }

                    if (realCash.doubleValue() < 0) {
                        // 直接结算
                        Result<Order> result = null;
                        Driver driver = driverService.findOne(order.getDriverId());
                        result = orderService
                            .completeTaskNewV3(order, passenger, driver, "renBaoPay", null,
                                hasPayed,
                                false);
                        if (result.isSuccess()) {
                            // 完成工单事件
                            ReactorVo rVo = new ReactorVo();
                            rVo.setDriver(driver);
                            rVo.setOrder(order);
                            OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                            applicationEventMulticaster.multicastEvent(finishEvent);
                            if (null != passenger) {
                                ReactorVo rVo2 = new ReactorVo();
                                rVo2.setOrderChannelName(order.getOrderType());
                                rVo2.setOrderType(OrderType.daijia);
                                rVo2.setPassenger(passenger);
                                rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(
                                    rVo2);
                                applicationEventMulticaster.multicastEvent(activityCheckEvent);

                                MemberRebateEvent memberRebateEvent = new MemberRebateEvent(
                                    passenger, order,
                                    order.getRealCash(), 1);
                                applicationEventMulticaster.multicastEvent(memberRebateEvent);
                            }
                            map.put("success", true);
                            map.put("type", "hasfinished");
                            return map;
                        } else {
                            map.put("success", false);
                            map.put("message", result.getMessage());
                            return map;
                        }
                    } else {
                        order.setRealCash(realCash);
                    }
                    // 确认并报单
                    orderService.reportV3(order, xml);

                    zWYApi.syncOrderInfo(order.getOrderNoRenBao(), order.getCuponNoRenBao(),
                        order.getOrderNumber(),
                        String.valueOf(5), order.getClientPhone());
                }
                // 客户端提醒付费推送
                OrderConfirmEvent orderConfirmEvent = new OrderConfirmEvent(order);
                applicationEventMulticaster.multicastEvent(orderConfirmEvent);

                map.put("success", true);
                map.put("type", "waitfinish");
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
            map.put("success", false);
            map.put("message", "内部服务器错误");
            return map;
        }

    }

    /***
     * 完成任务
     * @param orderId
     * @param payType
     * @param who
     * @return
     */
    @RequestMapping(value = "finishTask", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> finishTask(Long orderId, String payType, String who) {

        logger.error("recv orderId:{},payType{}", orderId, payType);

        Map<String, Object> map = new HashMap<String, Object>();

        if (null == orderId || StringUtils.isBlank(payType)) {
            map.put("success", false);
            map.put("message", "参数错误");
            return map;
        }

        if (!"helppay".equals(payType) && !"sign".equals(payType) && !"balance".equals(payType)) {
            map.put("success", false);
            map.put("message", "支付方式应为代付、签单、余额中的一种");
            return map;
        }

        Order order = orderService.findOne(orderId);

        if (null == order) {
            map.put("success", false);
            map.put("message", "订单不存在");
            return map;
        }

        if (order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
            || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            map.put("success", false);
            map.put("message", "订单已结算");
            return map;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            map.put("success", false);
            map.put("message", "订单状态不正确");
            return map;
        }

        if (!order.isTreatment()) {
            map.put("success", false);
            map.put("message", "还未确认订单，不能结算");
            return map;
        }

        Driver driver = driverService.findOne(order.getDriverId());
        if ("helppay".equals(payType)) {// 如果是代付，服务人员收到现金，余额减钱
            if (null == driver) {
                map.put("success", false);
                map.put("message", "订单服务人员不存在，无法代付");
                return map;
            }
        }

        Passenger passenger = memberService.findOnePassenger(order.getClientId());
        if (null != passenger) {
            if ("sign".equals(payType)) {// 签单支付
                if (!passenger.isAllowOverdraw()) {
                    map.put("success", false);
                    map.put("message", "当前客户不能签单");
                    return map;
                }
            } else if ("balance".equals(payType)) {// 余额支付

                BigDecimal afterPayMoney = BigDecimal.ZERO;
                if (null != order.getPrePayTypeDetail()) {
                    if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                        afterPayMoney = order.getRealCash().subtract(order.getCouponMoney());
                    } else {
                        afterPayMoney = order.getRealCash().subtract(order.getShouldCash());
                    }
                } else {
                    afterPayMoney = order.getRealCash();
                }

                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                    if (passenger.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < (afterPayMoney.doubleValue())) {
                        map.put("success", false);
                        map.put("message", "余额不足");
                        return map;
                    }
                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                    if (enterprise.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < (afterPayMoney.doubleValue())) {
                        map.put("success", false);
                        map.put("message", "余额不足");
                        return map;
                    }
                }

            }
        }

        try {

            Result<Order> result = orderService
                .completeTaskNewV3(order, passenger, driver, "clickPay", payType, null,
                    false);

            if (result.isSuccess()) {

                // 完成工单事件
                ReactorVo rVo = new ReactorVo();
                rVo.setDriver(driver);
                rVo.setOrder(order);

                if (StringUtils.isNotBlank(who) && who.equals("passenger")) {
                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver,
                        order.getId(), "daijia");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);
                }

                OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                applicationEventMulticaster.multicastEvent(finishEvent);

                if (null != passenger) {
                    ReactorVo rVo2 = new ReactorVo();
                    rVo2.setOrderChannelName(order.getOrderType());
                    rVo2.setOrderType(OrderType.daijia);
                    rVo2.setPassenger(passenger);
                    rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                    ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                    applicationEventMulticaster.multicastEvent(activityCheckEvent);

                    MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger, order,
                        order.getRealCash(),
                        1);
                    applicationEventMulticaster.multicastEvent(memberRebateEvent);
                }

                map.put("success", true);
                return map;
            } else {
                map.put("success", false);
                map.put("message", result.getMessage());
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
            map.put("success", false);
            map.put("message", "内部服务器错误");
            return map;
        }

    }

    /***
     *  查询订单
     * @param orderId
     * @return
     */
    @RequestMapping(value = "clientPayData", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> clientPayData(Long orderId) {

        Map<String, Object> map = new HashMap<String, Object>();

        Setting setting = settingUtils.get();

        Order order = orderService.findOne(orderId);

        BigDecimal coupon_hasPayed = order.getCouponMoney();

        map.put("couponMoney", coupon_hasPayed);

        map.put("realCash", order.getRealCash().subtract(order.getGuoluMoney()));
        map.put("guoluMoney", order.getGuoluMoney());
        map.put("yuanchengMoney", order.getYuanchengMoney());
        map.put("otherMoney", order.getOtherMoney());

        // 微信v5新加返回
        map.put("travelTime", order.getTravelTime());
        map.put("travelPrice", order.getTravelPrice());
        map.put("waitedTime", order.getWaitedTime());
        map.put("waitedPrice", order.getWaitedPrice());
        BigDecimal hasPayed = BigDecimal.ZERO;// 之前已经实际支付的钱
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                map.put("preyMoney", BigDecimal.ZERO);
            } else {
                hasPayed = hasPayed.add(order.getSignMoney());

                hasPayed = hasPayed.add(order.getBalanceMoney());

                hasPayed = hasPayed.add(order.getAlipayMoney());

                hasPayed = hasPayed.add(order.getWeixinMoney());

                hasPayed = hasPayed.add(order.getUnionpayMoney());

                hasPayed = hasPayed.add(order.getBestpayMoney());

                map.put("preyMoney", hasPayed);
            }
        } else {
            map.put("preyMoney", BigDecimal.ZERO);
        }

        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().toString().contains(PayTypeDetails.coupon.toString())) {
                BigDecimal payMoney = order.getRealCash();// 还需支付的钱
                payMoney = payMoney.subtract(order.getGuoluMoney());
                payMoney = payMoney.subtract(coupon_hasPayed);
                payMoney = payMoney.subtract(hasPayed);
                if (payMoney.doubleValue() < 0) {
                    payMoney = BigDecimal.ZERO;
                }
                payMoney = payMoney.add(order.getGuoluMoney());

                map.put("payMoney", payMoney);
            } else {
                map.put("payMoney", order.getRealCash().subtract(order.getShouldCash()));
            }
        } else {
            map.put("payMoney", order.getRealCash());
        }

        Boolean aliPay = true;
        Boolean weixinPay = true;

        if (StringUtils.isBlank(setting.getAlipayPartnerID()) || StringUtils
            .isBlank(setting.getAlipaySellerID())
            || StringUtils.isBlank(setting.getAlipayPartnerPrivKey())) {
            aliPay = false;
        }
        if (StringUtils.isBlank(setting.getWxAppID()) || StringUtils
            .isBlank(setting.getWxAppSecret())
            || StringUtils.isBlank(setting.getWxPartnerID()) || StringUtils
            .isBlank(setting.getWxPartnerKey())) {
            weixinPay = false;
        }
        Boolean unionPay = true;
        if (StringUtils.isBlank(setting.getMerId()) || StringUtils.isBlank(setting.getAcpProdEnc())
            || StringUtils.isBlank(setting.getAcpProdMiddle()) || StringUtils
            .isBlank(setting.getAcpProdRoot())
            || StringUtils.isBlank(setting.getAcpsdkSignCertPath())
            || StringUtils.isBlank(setting.getAcpsdkSignCertPwd())) {
            unionPay = false;
        }
        map.put("unionPay", unionPay);

        map.put("weixinPay", weixinPay);
        map.put("aliPay", aliPay);

        Passenger passenger = memberService.findOnePassenger(order.getClientId());
        if (passenger.getType() == Passenger.TYPE_PASSENGER) {
            map.put("overdraw", passenger.isAllowOverdraw());
        } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
            Enterprise enterprise = memberService.findOneEnterprise(passenger.getEnterprise_id());
            map.put("overdraw", enterprise.isAllowOverdraw());
        }

        map.put("success", true);
        return map;
    }

    /***
     * 客户端APP后支付
     * @param response
     * @param request
     * @param orderId
     * @return
     */
    @RequestMapping(value = "alipay/afterpay")
    public @ResponseBody
    Map<String, Object> alipayAfterpay(HttpServletResponse response, HttpServletRequest request,
        Long orderId) {
        Map<String, Object> mapData = new HashMap<String, Object>();
        try {

            Order order = orderService.findOne(orderId);

            if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                mapData.put("success", false);
                mapData.put("message", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode());
                return mapData;
            }

            if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
                mapData.put("success", false);
                mapData.put("message", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_STATUS_ERROR.getCode());
                return mapData;
            }

            if (!order.isTreatment()) {
                mapData.put("success", false);
                mapData.put("message", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_NOT_CONFIRM.getCode());
                return mapData;
            }

            BigDecimal money = BigDecimal.ZERO;
            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    money = order.getRealCash().subtract(order.getCouponMoney());
                } else {
                    money = order.getRealCash().subtract(order.getShouldCash());
                }
            } else {
                money = order.getRealCash();
            }

            PayRecordOrder payRecordOrder = new PayRecordOrder();
            payRecordOrder.setMoney(money);
            payRecordOrder.setOrderId(orderId);
            payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.alipay);
            payRecordOrder.setTreatment(false);
            payRecordOrderService.insertRecord(payRecordOrder);

            Setting setting = settingUtils.get();

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("PartnerID", setting.getAlipayPartnerID());
            map.put("SellerID", setting.getAlipaySellerID());
            map.put("PartnerPrivKey", setting.getAlipayPartnerPrivKey());
            map.put("PartnerPublicKey", AlipayConfig.ali_public_key);
            map.put("tradeNO", "dj_af_" + payRecordOrder.getId() + "_" + order.getId());
            map.put("productName", "代驾结算付费");
            map.put("productDescription", "代驾结算付费");
            map.put("amount", money);
            map.put("notifyURL", setting.getWebUrl() + "/api/daijia/alipay/afternotify");
            String content = MemberOrderSign.sign(map);
            String sign = RSA.sign(content, setting.getAlipayPartnerPrivKey(), "utf-8");
            sign = URLEncoder.encode(sign, "utf-8");
            String url = content + "&sign=\"" + sign + "\"&sign_type=\"RSA\"";
            mapData.put("success", true);
            mapData.put("url", url);
        } catch (Exception e) {
            mapData.put("success", false);
            mapData.put("message", "支付接口请求失败");
        }
        return mapData;
    }

    // 支付宝支付后的接口
    @RequestMapping(value = "alipay/afternotify")
    public synchronized @ResponseBody
    String alipayAfterNotify(HttpServletResponse response, HttpServletRequest request)
        throws UnsupportedEncodingException {
        Setting setting = settingUtils.get();
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr =
                    (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }

            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        // 商户订单号
        String out_trade_no = new String(
            request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        // 支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 交易状态
        String trade_status = new String(
            request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        logger.error("商户订单号：" + out_trade_no);
        logger.error("交易号：" + trade_no + "交易状态：" + trade_status);
        if (AlipayNotify.verify(params, setting)) {// 验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = payRecordOrderService.findOne(orderId);
                if (payRecordOrder.isTreatment()) {
                    return "success";
                }

                Order order = orderService.findOne(payRecordOrder.getOrderId());

                if (order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
                    || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                    return "success";
                }

                Passenger passenger = memberService.findOnePassenger(order.getClientId());
                Driver driver = driverService.findOne(order.getDriverId());

                Result<Order> result = orderService
                    .completeTaskNewV3(order, passenger, driver, "onlinePay", "alipay",
                        null, false);

                if (result.isSuccess()) {

                    // 完成工单事件
                    ReactorVo rVo = new ReactorVo();
                    rVo.setDriver(driver);
                    rVo.setOrder(order);

                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver,
                        order.getId(), "daijia");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                    OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                    applicationEventMulticaster.multicastEvent(finishEvent);

                    if (null != passenger) {
                        ReactorVo rVo2 = new ReactorVo();
                        rVo2.setOrderChannelName(order.getOrderType());
                        rVo2.setOrderType(OrderType.daijia);
                        rVo2.setPassenger(passenger);
                        rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                        ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                        applicationEventMulticaster.multicastEvent(activityCheckEvent);

                        MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger,
                            order,
                            order.getRealCash(), 1);
                        applicationEventMulticaster.multicastEvent(memberRebateEvent);
                    }

                    return "success";
                } else {
                    return "fail";
                }

            } else if (trade_status.equals("TRADE_SUCCESS")) {
                // 调用专车系统支付成功,把临时表的订单信息新增到真实表中
                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = payRecordOrderService.findOne(orderId);
                if (payRecordOrder.isTreatment()) {
                    return "success";
                }

                Order order = orderService.findOne(payRecordOrder.getOrderId());

                if (order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
                    || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                    return "success";
                }

                Passenger passenger = memberService.findOnePassenger(order.getClientId());
                Driver driver = driverService.findOne(order.getDriverId());

                Result<Order> result = orderService
                    .completeTaskNewV3(order, passenger, driver, "onlinePay", "alipay",
                        null, false);

                if (result.isSuccess()) {

                    // 完成工单事件
                    ReactorVo rVo = new ReactorVo();
                    rVo.setDriver(driver);
                    rVo.setOrder(order);

                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver,
                        order.getId(), "daijia");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                    OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                    applicationEventMulticaster.multicastEvent(finishEvent);

                    if (null != passenger) {
                        ReactorVo rVo2 = new ReactorVo();
                        rVo2.setOrderChannelName(order.getOrderType());
                        rVo2.setOrderType(OrderType.daijia);
                        rVo2.setPassenger(passenger);
                        rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                        ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                        applicationEventMulticaster.multicastEvent(activityCheckEvent);

                        MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger,
                            order,
                            order.getRealCash(), 1);
                        applicationEventMulticaster.multicastEvent(memberRebateEvent);
                    }

                    return "success";
                } else {
                    return "fail";
                }

            }

            return "fail";
        } else {
            return "fail";
        }

    }

    // 微信支付前接口
    @RequestMapping(value = "wx/afterpay")
    public synchronized @ResponseBody
    SortedMap<String, String> wxAfterpay(HttpServletResponse response,
        HttpServletRequest request, Long orderId) {

        Order order = orderService.findOne(orderId);

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();

        if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
            finalpackage
                .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
            return finalpackage;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
            return finalpackage;
        }

        if (!order.isTreatment()) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
            return finalpackage;
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = order.getRealCash().subtract(order.getCouponMoney());
            } else {
                money = order.getRealCash().subtract(order.getShouldCash());
            }
        } else {
            money = order.getRealCash();
        }

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.weixin);
        payRecordOrder.setTreatment(false);
        payRecordOrderService.insertRecord(payRecordOrder);

        Setting setting = settingUtils.get();
        String createOrderURL = Configuration.createOrderURL;

        // 商户相关资料
        String appid = setting.getWxAppID();
        String appsecret = setting.getWxAppSecret();
        String partner = setting.getWxPartnerID();
        String partnerkey = setting.getWxPartnerKey();

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "代驾结算付费-" + order.getOrderNumber();
        // 商户订单号
        String out_trade_no = "dj_af_" + payRecordOrder.getId() + "_" + order.getId();
        // 总金额以分为单位，不带小数点
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = setting.getWebUrl() + "/api/daijia/wx/afternotify";

        String trade_type = "APP";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>"
            + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + body
            + "]]></body>"
            + "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
            // "<total_fee>"+1+"</total_fee>"+
            "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip
            + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>"
            + trade_type
            + "</trade_type>" + "</xml>";

        String prepay_id = "";
        try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                logger.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appid", appid);
        finalpackage.put("partnerid", partner);
        finalpackage.put("prepayid", prepay_id);
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("noncestr", nonce_str);
        finalpackage.put("timestamp", timestamp);
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("sign", finalsign);

        finalpackage.put("success", Boolean.TRUE.toString());

        return finalpackage;

    }

    // 微信支付后接口
    @RequestMapping("wx/afternotify")
    public synchronized @ResponseBody
    String wxAfterNotify(HttpServletResponse response, HttpServletRequest request)
        throws Exception {

        String out_trade_no = "";

        try {

            BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            String strxml = sb.toString();

            InputStream in = new ByteArrayInputStream(strxml.getBytes());
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                if (k.equals("out_trade_no")) {
                    out_trade_no = e.getText();
                }
            }

            try {
                // 关闭流
                if (null != in) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (StringUtils.isBlank(out_trade_no)) {
                return "FAIL";
            }

            Long orderId = Long.valueOf(out_trade_no.split("_")[2]);

            PayRecordOrder payRecordOrder = payRecordOrderService.findOne(orderId);
            if (payRecordOrder.isTreatment()) {
                return "SUCCESS";
            }

            Order order = orderService.findOne(payRecordOrder.getOrderId());

            if (order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
                || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                return "SUCCESS";
            }

            Passenger passenger = memberService.findOnePassenger(order.getClientId());
            Driver driver = driverService.findOne(order.getDriverId());

            Result<Order> result = orderService
                .completeTaskNewV3(order, passenger, driver, "onlinePay", "weixin", null,
                    false);

            if (result.isSuccess()) {

                // 完成工单事件
                ReactorVo rVo = new ReactorVo();
                rVo.setDriver(driver);
                rVo.setOrder(order);

                OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                    driver,
                    order.getId(), "daijia");
                applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                applicationEventMulticaster.multicastEvent(finishEvent);

                if (null != passenger) {
                    ReactorVo rVo2 = new ReactorVo();
                    rVo2.setOrderChannelName(order.getOrderType());
                    rVo2.setOrderType(OrderType.daijia);
                    rVo2.setPassenger(passenger);
                    rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                    ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                    applicationEventMulticaster.multicastEvent(activityCheckEvent);

                    MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger, order,
                        order.getRealCash(),
                        1);
                    applicationEventMulticaster.multicastEvent(memberRebateEvent);
                }

                return "SUCCESS";
            } else {
                return "FAIL";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }

    }

    // 微信支付前接口
    @RequestMapping(value = "wx/prepayId_jsapi")
    public @ResponseBody
    SortedMap<String, String> prepayIdJsapi(HttpServletResponse response,
        HttpServletRequest request, Long orderId, String openid) {
        Order order = orderService.findOne(orderId);

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();

        if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
            finalpackage
                .put("code", String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()));
            return finalpackage;
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_STATUS_ERROR.getCode()));
            return finalpackage;
        }

        if (!order.isTreatment()) {
            finalpackage.put("success", String.valueOf(false));
            finalpackage.put("message", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
            finalpackage.put("code", String.valueOf(ErrorConstantV4.ORDER_NOT_CONFIRM.getCode()));
            return finalpackage;
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = order.getRealCash().subtract(order.getCouponMoney());
            } else {
                money = order.getRealCash().subtract(order.getShouldCash());
            }
        } else {
            money = order.getRealCash();
        }

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.weixin);
        payRecordOrder.setTreatment(false);
        payRecordOrderService.insertRecord(payRecordOrder);

        Setting setting = settingUtils.get();
        WxSetting wxSetting = settingUtils.getWx();

        String createOrderURL = Configuration.createOrderURL;

        // 商户相关资料
        String appid = wxSetting.getWxAppId();
        String appsecret = wxSetting.getWxAppSecret();
        String partner = wxSetting.getWxPartnerId();
        String partnerkey = wxSetting.getWxPartnerKey();

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "代驾订单-" + order.getOrderNumber();
        // 商户订单号
        String out_trade_no = "dj_js_" + payRecordOrder.getId() + "_" + order.getId();
        // 总金额以分为单位，不带小数点
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = setting.getWebUrl() + "/api/daijia/wx/afternotify";

        String trade_type = "JSAPI";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("openid", openid);
        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>"
            + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + body
            + "]]></body>"
            + "<out_trade_no>" + out_trade_no + "</out_trade_no>" + "<total_fee>" + total_fee
            + "</total_fee>"
            + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" + "<notify_url>"
            + notify_url
            + "</notify_url>" + "<trade_type>" + trade_type + "</trade_type>" + "<openid>" + openid
            + "</openid>"
            + "</xml>";
        String prepay_id = "";
        try {
            prepay_id = GetWxOrderno.getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                logger.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appId", appid);
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("package", "prepay_id=" + prepay_id + "");
        finalpackage.put("signType", "MD5");
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("paySign", finalsign);

        return finalpackage;

    }

    // 微信小程序支付
    @RequestMapping(value = "wx/miniProgramPay")
    public synchronized @ResponseBody
    ResultTransport miniProgramPay(HttpServletResponse response,
        HttpServletRequest request, Long orderId, String jsCode) {

        Order order = orderService.findOne(orderId);

        if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (!order.isTreatment()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_CONFIRM);
        }

        WxSetting wxSetting = settingUtils.getWx();
        Setting sysSetting = settingUtils.get();

        // 商户相关资料
        String appid = wxSetting.getWxAppIdMP();
        String appsecret = wxSetting.getWxAppSecretMP();
        String partner = wxSetting.getWxPartnerIdMP();
        String partnerkey = wxSetting.getWxPartnerKeyMP();

        // 验证是否得到了APPID/APPSECRET/jsCode
        if (null == appid || appid.isEmpty()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.APPID_NOT_SET);
        }
        if (null == appsecret || appsecret.isEmpty()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.APPSECRET_NOT_SET);
        }
        if (null == jsCode || jsCode.isEmpty()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.JSCODE_IS_EMPTY);
        }

        // 获取该用户的openid
        String openid = WeixinUtil.getOpenid(appid, appsecret, jsCode);
        if (openid == null) {
            return ResultTransport.getErrorBy(ErrorConstantV4.GET_USER_OPENID_ERROR);
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = order.getRealCash().subtract(order.getCouponMoney());
            } else {
                money = order.getRealCash().subtract(order.getShouldCash());
            }
        } else {
            money = order.getRealCash();
        }

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.weixin);
        payRecordOrder.setTreatment(false);
        payRecordOrderService.insertRecord(payRecordOrder);

        String createOrderURL = Configuration.createOrderURL;

        // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(6) + "";
        // 10位序列号,可以自行调整。
        String strReq = strTime + strRandom;
        // 商户号
        String mch_id = partner;
        // 随机数
        String nonce_str = strReq;
        // 商品描述
        String body = "代驾结算付费-" + order.getOrderNumber();
        // 商户订单号
        String out_trade_no = "dj_af_" + payRecordOrder.getId() + "_" + order.getId();
        // 总金额以分为单位，不带小数点
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue());
        // 订单生成的机器 IP
        String spbill_create_ip = request.getRemoteAddr();

        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String notify_url = sysSetting.getWebUrl() + "/api/daijia/wx/afternotify";

        String trade_type = "JSAPI";

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);

        // 这里写的金额为1 分到时修改
        // packageParams.put("total_fee", "1");
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("openid", openid);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
            + "<nonce_str>"
            + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + body
            + "]]></body>"
            + "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
            // "<total_fee>"+1+"</total_fee>"+
            "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip
            + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>"
            + trade_type
            + "</trade_type>" + "<openid>" + openid + "</openid>" + "</xml>";

        String prepay_id = "";
        try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
                logger.error("统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        String timestamp = Sha1Util.getTimeStamp();
        finalpackage.put("appId", appid);
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("package", "prepay_id=" + prepay_id);
        finalpackage.put("signType", "MD5");
        finalpackage.put("timeStamp", timestamp);
        String finalsign = reqHandler.createSign(finalpackage);
        finalpackage.put("sign", finalsign);

        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        instance.setData(finalpackage);
        return instance;
    }

    /**
     * 根据公司id查询微信广告
     *
     * @param companyId
     * @return
     */
    @RequestMapping(value = "advertisement", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> advertisement(@RequestParam("companyId") Long companyId) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            List<Advertisement> lsit = advertisementService.findByCompanyId(companyId);

            map.put("code", 0);
            map.put("message", "成功");
            map.put("data", lsit);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", -1);
            map.put("message", "查询失败");
            map.put("data", null);
        }
        return map;
    }

    /**
     * 银联支付(代驾订单预支付).
     */
    @RequestMapping(value = "unionpay/prepay")
    public @ResponseBody
    ResultTransport unionpayPrepay(HttpServletResponse response, HttpServletRequest request,
        Long orderId) {

        Setting setting = settingUtils.get();
        // 从classpath加载acp_sdk.properties文件
        SDKConfig.getConfig().loadPropertiesFromSrc(setting);

        String payOrderId = DemoBase.getOrderId();
        OrderTemp temp = orderTempService.findOne(orderId);
        int money = temp.getPrepayCash().multiply(new BigDecimal(100))
            .intValue(); // txnAmt以'元'为单位,乘以100以'分'为单位传给银联
        String txnTime = DemoBase.getCurrentTime(); // 交易时间
        String merId = setting.getMerId(); // 获取商户号
        Map<String, String> contentData = new HashMap<String, String>();

        /*** 银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改 ***/
        contentData.put("version", "5.1.0"); // 版本号 全渠道默认值
        contentData.put("encoding", "UTF-8"); // 字符集编码 可以使用UTF-8,GBK两种方式
        contentData.put("signMethod", "01"); // 签名方法
        contentData.put("txnType", "01"); // 交易类型 01:消费
        contentData.put("txnSubType", "01"); // 交易子类 01：消费
        contentData.put("bizType", "000201"); // 填写000201
        contentData.put("channelType", "08"); // 渠道类型 08手机

        /*** 商户接入参数 ***/
        contentData.put("merId", merId); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
        contentData.put("accessType", "0"); // 接入类型，商户接入填0 ，不需修改（0：直连商户， 1： 收单机构
        // 2：平台商户）
        contentData.put("orderId", payOrderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
        contentData.put("txnTime", txnTime); // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
        contentData.put("accType", "01"); // 账号类型 01：银行卡02：存折03：IC卡帐号类型(卡介质)
        contentData.put("txnAmt", String.valueOf(money)); // 交易金额 单位为分，不能带小数点
        // contentData.put("txnAmt", String.valueOf(1)); //交易金额 单位为分，不能带小数点
        contentData.put("currencyCode", "156"); // 境内商户固定 156 人民币
        String out_trade_no = "daijia_prepay_" + orderId;
        contentData.put("reqReserved", out_trade_no);
        String backUrl = "";
        if (setting.getWebUrl().endsWith("/")) {
            backUrl = setting.getWebUrl() + "api/daijia/unionpay/notify";
        } else {
            backUrl = setting.getWebUrl() + "/" + "api/daijia/unionpay/notify";
        }
        contentData.put("backUrl", backUrl);

        /** 对请求参数进行签名并发送http post请求，接收同步应答报文 **/
        Map<String, String> reqData = AcpService.sign(contentData,
            DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
        String requestAppUrl = SDKConfig.getConfig()
            .getAppRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
        // acpsdk.backTransUrl
        Map<String, String> rspData = AcpService.post(reqData, requestAppUrl,
            DemoBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过

        /** 对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考-------------> **/
        // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
        if (!rspData.isEmpty()) {
            if (AcpService.validate(rspData, DemoBase.encoding)) {
                LogUtil.writeLog("验证签名成功");
                String respCode = rspData.get("respCode");
                if (("00").equals(respCode)) {
                    // 成功,获取tn交易流水号
                    String tn = rspData.get("tn");
                    ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                    instance.setData(tn);
                    return instance;
                } else {
                    // 其他应答码为失败请排查原因或做失败处理
                    return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
                }
            } else {
                LogUtil.writeErrorLog("验证签名失败");
                return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            }
        } else {
            // 未返回正确的http状态
            LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    /**
     * 银联支付代驾订单预支付回调.
     */
    @RequestMapping(value = "unionpay/notify")
    public synchronized @ResponseBody
    void unionpayNotify(HttpServletResponse resp, HttpServletRequest req)
        throws Exception {

        String encoding = req.getParameter(SDKConstants.param_encoding);
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = getAllRequestParam(req);

        LogUtil.printRequestLog(reqParam);

        Map<String, String> valideData = null;
        if (null != reqParam && !reqParam.isEmpty()) {
            Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
            valideData = new HashMap<String, String>(reqParam.size());
            while (it.hasNext()) {
                Entry<String, String> e = it.next();
                String key = (String) e.getKey();
                String value = (String) e.getValue();

                valideData.put(key, value);
            }
        }

        // 重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
        if (!AcpService.validate(valideData, encoding)) {
            LogUtil.writeLog("验证签名结果[失败].");
        } else {
            LogUtil.writeLog("验证签名结果[成功].");

            LogUtil.writeLog("后台通知的数据orderId:" + valideData.get("orderId"));
            String respCode = valideData.get("respCode");

            if ("00".equals(respCode)) {
                String out_trade_no = valideData.get("reqReserved"); // 获取后台通知的数据，其他字段也可用类似方式获取

                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                OrderTemp temp = orderTempService.findOne(orderId);
                if (!temp.isTreatment()) {

                    Order order = new Order();
                    if (null != temp.getOrderNoRenBao() && null != temp.getCuponNoRenBao()) {
                        order.setOrderNoRenBao(temp.getOrderNoRenBao());
                        order.setCuponNoRenBao(temp.getCuponNoRenBao());
                    }
                    order.setClientId(temp.getClientId());
                    order.setClientName(temp.getClientName());
                    order.setClientPhone(temp.getClientPhone());
                    order.setUserPhone(temp.getUserPhone());
                    order.setFromPlace(temp.getFromPlace());
                    order.setClientLatitude(temp.getClientLatitude());
                    order.setClientLongitude(temp.getClientLongitude());
                    order.setToPlace(temp.getToPlace());
                    order.setToPlaceLatitude(temp.getToPlaceLatitude());
                    order.setToPlaceLongitude(temp.getToPlaceLongitude());
                    order.setServerTime(temp.getServerTime());
                    order.setOrderCarType(OrderCarType.daijia);
                    order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
                    order.setUnionpayMoney(temp.getPrepayCash());
                    order.setFromSource(Order.ORDER_TYPE_APP);
                    order.setOrderType(Order.ORDER_TYPE_APP);

                    Coupon coupon = null;
                    if (null != temp.getCouponId()) {
                        coupon = couponService.findOne(temp.getCouponId());
                    }

                    if (null != coupon) {
                        order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_unionpay);
                    } else {
                        order.setPrePayTypeDetail(Order.PayTypeDetails.unionpay);
                    }

                    Long[] couponIds = null;
                    if (null != coupon) {
                        couponIds = new Long[1];
                        couponIds[0] = coupon.getId();
                    }

                    Result<Order> result = orderService
                        .create(order, 1, couponIds, temp.getClientLongitude(),
                            temp.getClientLatitude(), temp.getCompanyId(), null, null,
                            temp.getShouldCash());

                    if (result.isSuccess()) {
                        // 更新为交易成功
                        orderTempService.updateTreatment(temp.getId());

                        // 客户消费记录
                        Order newOrder = result.getData().get(0);

                        Passenger passenger = memberService.findOnePassenger(temp.getClientId());

                        String payMemo = "订单【" + newOrder.getOrderNumber() + "】预付费使用银联支付"
                            + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString()
                            + "元。";

                        if (null != coupon) {
                            if (coupon.getCouponRule().getType()
                                .equals(CouponRule.TYPE_DEDUCTION)) {
                                payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";
                            } else if (coupon.getCouponRule().getType()
                                .equals(CouponRule.TYPE_DISCOUNT)) {
                                payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
                            }
                        }

                        if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                            memberService
                                .money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                                    PassengerAccount.OPERATING_SYS,
                                    PassengerAccount.PayType.PAYTYPE_UNIONPAY,
                                    newOrder.getId(), newOrder.getOrderNumber(),
                                    PassengerAccount.ORDER_TYPE_DAIJIA,
                                    null, false, false);
                        } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                            Enterprise enterprise = memberService
                                .findOneEnterprise(passenger.getEnterprise_id());
                            if (null != enterprise) {
                                memberService
                                    .moneyEnterprise(enterprise, temp.getPrepayCash().negate(),
                                        payMemo,
                                        PassengerAccount.OPERATING_SYS,
                                        PassengerAccount.PayType.PAYTYPE_UNIONPAY,
                                        newOrder.getId(), newOrder.getOrderNumber(),
                                        PassengerAccount.ORDER_TYPE_DAIJIA,
                                        null, false, false);
                            }
                        }

                        for (Order order2 : result.getData()) {
                            OrderCreateEvent event = new OrderCreateEvent(order2);
                            applicationEventMulticaster.multicastEvent(event);

                            OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                            applicationEventMulticaster.multicastEvent(orderRecordEvent);
                        }

                        OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
                        applicationEventMulticaster.multicastEvent(newRushEvent);

                    }
                }
                // 返回给银联服务器http 200 状态码
                resp.getWriter().print("ok");
            }
        }
        LogUtil.writeLog("BackRcvResponse接收后台通知结束");

    }

    /**
     * 客户端APP后支付
     */
    @RequestMapping(value = "unionpay/afterpay")
    public @ResponseBody
    Map<String, Object> unionpayAfterpay(HttpServletResponse response, HttpServletRequest request,
        Long orderId) {
        Map<String, Object> mapData = new HashMap<String, Object>();
        try {

            Order order = orderService.findOne(orderId);

            if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                mapData.put("message", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode());
                return mapData;
            }

            if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
                mapData.put("message", ErrorConstantV4.ORDER_STATUS_ERROR.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_STATUS_ERROR.getCode());
                return mapData;
            }

            if (!order.isTreatment()) {
                mapData.put("message", ErrorConstantV4.ORDER_NOT_CONFIRM.getMessage());
                mapData.put("code", ErrorConstantV4.ORDER_NOT_CONFIRM.getCode());
                return mapData;
            }

            BigDecimal money = BigDecimal.ZERO;
            if (null != order.getPrePayTypeDetail()) {
                if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                    money = order.getRealCash().subtract(order.getCouponMoney());
                } else {
                    money = order.getRealCash().subtract(order.getShouldCash());
                }
            } else {
                money = order.getRealCash();
            }

            PayRecordOrder payRecordOrder = new PayRecordOrder();
            payRecordOrder.setMoney(money);
            payRecordOrder.setOrderId(orderId);
            payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.unionpay);
            payRecordOrder.setTreatment(false);
            payRecordOrderService.insertRecord(payRecordOrder);

            Setting setting = settingUtils.get();
            // 从classpath加载acp_sdk.properties文件
            SDKConfig.getConfig().loadPropertiesFromSrc(setting);

            String payOrderId = DemoBase.getOrderId();
            OrderTemp temp = orderTempService.findOne(orderId);
            int paymoney = money.multiply(new BigDecimal(100))
                .intValue(); // txnAmt以'元'为单位,乘以100以'分'为单位传给银联
            String txnTime = DemoBase.getCurrentTime(); // 交易时间
            String merId = setting.getMerId(); // 获取商户号
            Map<String, String> contentData = new HashMap<String, String>();

            /*** 银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改 ***/
            contentData.put("version", "5.1.0"); // 版本号 全渠道默认值
            contentData.put("encoding", "UTF-8"); // 字符集编码 可以使用UTF-8,GBK两种方式
            contentData.put("signMethod", "01"); // 签名方法
            contentData.put("txnType", "01"); // 交易类型 01:消费
            contentData.put("txnSubType", "01"); // 交易子类 01：消费
            contentData.put("bizType", "000201"); // 填写000201
            contentData.put("channelType", "08"); // 渠道类型 08手机

            /*** 商户接入参数 ***/
            contentData.put("merId", merId); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
            contentData.put("accessType", "0"); // 接入类型，商户接入填0 ，不需修改（0：直连商户， 1： 收单机构
            // 2：平台商户）
            contentData.put("orderId", payOrderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
            contentData
                .put("txnTime", txnTime); // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
            contentData.put("accType", "01"); // 账号类型 01：银行卡02：存折03：IC卡帐号类型(卡介质)
            contentData.put("txnAmt", String.valueOf(paymoney)); // 交易金额 单位为分，不能带小数点
            contentData.put("currencyCode", "156"); // 境内商户固定 156 人民币
            String out_trade_no = "dj_af_" + payRecordOrder.getId() + "_" + order.getId();
            contentData.put("reqReserved", out_trade_no);
            String backUrl = "";
            if (setting.getWebUrl().endsWith("/")) {
                backUrl = setting.getWebUrl() + "api/daijia/unionpay/afternotify";
            } else {
                backUrl = setting.getWebUrl() + "/" + "api/daijia/unionpay/afternotify";
            }
            contentData.put("backUrl", backUrl);

            /** 对请求参数进行签名并发送http post请求，接收同步应答报文 **/
            Map<String, String> reqData = AcpService.sign(contentData,
                DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
            String requestAppUrl = SDKConfig.getConfig()
                .getAppRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
            // acpsdk.backTransUrl
            Map<String, String> rspData = AcpService.post(reqData, requestAppUrl,
                DemoBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过

            /** 对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考-------------> **/
            // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
            if (!rspData.isEmpty()) {
                if (AcpService.validate(rspData, DemoBase.encoding)) {
                    LogUtil.writeLog("验证签名成功");
                    String respCode = rspData.get("respCode");
                    if (("00").equals(respCode)) {
                        // 成功,获取tn交易流水号
                        String tn = rspData.get("tn");
                        mapData.put("message", "成功");
                        mapData.put("code", 0);
                        mapData.put("data", tn);
                        return mapData;
                    } else {
                        mapData.put("message", "验证签名失败");
                        mapData.put("code", -1);
                        return mapData;
                    }
                } else {
                    mapData.put("message", "验证签名失败");
                    mapData.put("code", -1);
                    return mapData;
                }
            } else {
                mapData.put("message", "验证签名失败");
                mapData.put("code", -1);
                return mapData;
            }

        } catch (Exception e) {
            mapData.put("message", "支付接口请求失败");
            mapData.put("code", -4);
        }
        return mapData;
    }

    /**
     * 银联代驾订单结算时支付后回调接口
     *
     * @throws IOException
     */
    @RequestMapping(value = "unionpay/afternotify")
    public synchronized @ResponseBody
    void unionpayAfterNotify(HttpServletResponse resp, HttpServletRequest req)
        throws IOException {

        String encoding = req.getParameter(SDKConstants.param_encoding);
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = getAllRequestParam(req);

        LogUtil.printRequestLog(reqParam);

        Map<String, String> valideData = null;
        if (null != reqParam && !reqParam.isEmpty()) {
            Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
            valideData = new HashMap<String, String>(reqParam.size());
            while (it.hasNext()) {
                Entry<String, String> e = it.next();
                String key = (String) e.getKey();
                String value = (String) e.getValue();

                valideData.put(key, value);
            }
        }

        // 重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
        if (!AcpService.validate(valideData, encoding)) {
            LogUtil.writeLog("验证签名结果[失败].");
        } else {
            LogUtil.writeLog("验证签名结果[成功].");

            String respCode = valideData.get("respCode");

            if ("00".equals(respCode)) {
                String out_trade_no = valideData.get("reqReserved"); // 获取后台通知的数据，其他字段也可用类似方式获取

                Long orderId = Long.valueOf(out_trade_no.split("_")[2]);
                PayRecordOrder payRecordOrder = payRecordOrderService.findOne(orderId);
                if (!payRecordOrder.isTreatment()) {

                    Order order = orderService.findOne(payRecordOrder.getOrderId());

                    if (!order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
                        && !order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                        Passenger passenger = memberService.findOnePassenger(order.getClientId());
                        Driver driver = driverService.findOne(order.getDriverId());

                        Result<Order> result = orderService
                            .completeTaskNewV3(order, passenger, driver, "onlinePay",
                                "unionpay", null, false);

                        if (result.isSuccess()) {
                            // 完成工单事件
                            ReactorVo rVo = new ReactorVo();
                            rVo.setDriver(driver);
                            rVo.setOrder(order);

                            OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                                driver,
                                order.getId(), "daijia");
                            applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                            OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                            applicationEventMulticaster.multicastEvent(finishEvent);

                            if (null != passenger) {
                                ReactorVo rVo2 = new ReactorVo();
                                rVo2.setOrderChannelName(order.getOrderType());
                                rVo2.setOrderType(OrderType.daijia);
                                rVo2.setPassenger(passenger);
                                rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(
                                    rVo2);
                                applicationEventMulticaster.multicastEvent(activityCheckEvent);

                                MemberRebateEvent memberRebateEvent = new MemberRebateEvent(
                                    passenger, order,
                                    order.getRealCash(), 1);
                                applicationEventMulticaster.multicastEvent(memberRebateEvent);
                            }
                            // 返回给银联服务器http 200 状态码
                            resp.getWriter().print("ok");
                        }
                    }
                }
            }
        }
        LogUtil.writeLog("BackRcvResponse接收后台通知结束");

        /*
         *
         * Long orderId=Long.valueOf(out_trade_no.split("_")[2]); PayRecordOrder
         * payRecordOrder = payRecordOrderService.findOne(orderId);
         * if(payRecordOrder.isTreatment()){ return "success"; }
         *
         * Order order=orderService.findOne(payRecordOrder.getOrderId());
         *
         * if(order.getStatus().equals(Order.ORDER_STATUS_FINISHED) ||
         * order.getStatus().equals(Order.ORDER_STATUS_BAODAN)){ return "success"; }
         *
         * Passenger passenger = memberService.findOnePassenger(order.getClientId());
         * Driver driver = driverService.findOne(order.getDriverId());
         *
         * Result<Order> result = orderService.completeTaskNewV3(order,passenger,driver
         * ,"onlinePay","alipay",null,false);
         *
         * if(result.isSuccess()){
         *
         * //完成工单事件 ReactorVo rVo = new ReactorVo(); rVo.setDriver(driver);
         * rVo.setOrder(order);
         *
         * OrderPassengerHasPayEvent orderPassengerHasPayEvent= new
         * OrderPassengerHasPayEvent(driver,order.getId(),"daijia");
         * applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);
         *
         * OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
         * applicationEventMulticaster.multicastEvent(finishEvent);
         *
         * if(null!=passenger){ ReactorVo rVo2 = new ReactorVo();
         * rVo2.setOrderChannelName(order.getOrderType());
         * rVo2.setOrderType(OrderType.daijia); rVo2.setPassenger(passenger);
         * rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes); ActivityCheckEvent
         * activityCheckEvent = new ActivityCheckEvent(rVo2);
         * applicationEventMulticaster.multicastEvent(activityCheckEvent);
         *
         * MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger, order,
         * order.getRealCash(), 1);
         * applicationEventMulticaster.multicastEvent(memberRebateEvent); }
         *
         * return "success"; } else{ return "fail"; }
         */
    }

    /***************************************************************************************************
     *
     * 翼支付
     *
     ***************************************************************************************************/

    /**
     * 翼支付预先支付
     *
     * @param request 请求对象
     * @param orderId 订单号
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("bestpay/prepay")
    public synchronized ResultTransport bestPayByPrepay(HttpServletRequest request, Long orderId)
        throws Exception {

        ResultTransport transport = null;

        // 参数校验
        if (null == orderId || orderId.equals(0)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        // 获取系统设置
        Setting setting = settingUtils.get();
        String callBackUrl = setting.getWebUrl() + "/api/daijia/bestpay/notify";
        String createUrl = "https://webpaywg.bestpay.com.cn/order.action";

        // 获取商户信息
        String mch_id = setting.getMerchantId();
        String mch_key = setting.getMerKey();
        String mch_pwd = setting.getMchPwd();
        String riskInfo = setting.getRiskcontrolinfo();
        String attach_order_id = "daijia_prepay_" + orderId; // 商户订单号,这里作为附加信息，因为订单不能个包含特殊字符
        String body = "下单付款";

        // 使用随机数来作为订单流水号
        String currTime = TenpayUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length()); // 8位日期
        String strRandom = TenpayUtil.buildRandom(6) + ""; // 四位随机数
        String strReq = strTime + strRandom; // 10位序列号,可以自行调整

        // 查询出代驾的订单
        OrderTemp temp = orderTempService.findOne(orderId);
        String phone = temp.getClientPhone(); // 手机号
        BigDecimal money = temp.getPrepayCash(); // 预支付的金额

        // 格式化金额0.00
        DecimalFormat myformat = new java.text.DecimalFormat("0.00");
        String money_ = myformat.format(money);

        // 订单模型
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue()); // 元转分
        BestPayOrderModel orderModel = new BestPayOrderModel();
        orderModel.setATTACH(attach_order_id);
        orderModel.setCITYCODE("");
        orderModel.setDIVDETAILS("");
        orderModel.setENCODE("");
        orderModel.setENCODETYPE("1");
        orderModel.setKEY(mch_key);
        orderModel.setLOGINNO("");
        orderModel.setMERCHANTID(mch_id);
        orderModel.setORDERAMT(total_fee); // 分
        orderModel.setORDERCCY("RMB");
        orderModel.setORDERREQTIME(currTime);
        orderModel.setORDERREQTRANSEQ(strReq);
        orderModel.setORDERSEQ(strReq);
        orderModel.setPRODUCTDESC(body);
        orderModel.setPRODUCTID("04");
        orderModel.setPROVINCECODE("");
        orderModel.setRISKCONTROLINFO(riskInfo);
        orderModel.setSERVICECODE("05");
        orderModel.setSESSIONKEY("");
        orderModel.setSUBMERCHANTID("");
        orderModel.setTRANSCODE("01");
        boolean rs = BestPayCreateOrder.createByApp(createUrl, orderModel);

        // 下单失败
        if (!rs) {
            return ResultTransport.getErrorBy(ErrorConstantV4.BESTPAY_APP_CREATE_ORDER_ERR);
        }

        // 签名参数
        StringBuffer md5Buffer = new StringBuffer();
        md5Buffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
            .append(mch_id)
            .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
            .append("&BACKMERCHANTURL=").append(callBackUrl).append("&ORDERSEQ=").append(strReq)
            .append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=").append(currTime)
            .append("&ORDERVALIDITYTIME=").append("").append("&CURTYPE=").append("RMB")
            .append("&ORDERAMOUNT=")
            .append(money_).append("&SUBJECT=").append(body).append("&PRODUCTID=").append("04")
            .append("&PRODUCTDESC=").append(body).append("&CUSTOMERID=").append(phone)
            .append("&SWTICHACC=")
            .append("true").append("&KEY=").append(mch_key);

        // 签名
        logger.info("MAC(MD5)--before--String：" + md5Buffer.toString());
        String sign = CryptTool.md5Digest(md5Buffer.toString());
        logger.info("MAC(MD5)--after--String:" + sign);

        // 拼接返回数据串
        StringBuffer paramsBuffer = new StringBuffer();
        paramsBuffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
            .append(mch_id)
            // 签约商户号
            .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
            .append("&BACKMERCHANTURL=").append(callBackUrl).append("&SIGNTYPE=").append("MD5")
            .append("&SIGN=")
            .append(sign).append("&ORDERSEQ=").append(strReq).append("&ORDERREQTRANSEQ=")
            .append(strReq)
            .append("&ORDERTIME=").append(currTime).append("&ORDERVALIDITYTIME=").append("")
            .append("&ORDERAMOUNT=")
            .append(money_).append("&CURTYPE=").append("RMB").append("&PRODUCTID=").append("04")
            .append("&PRODUCTDESC=").append(body).append("&PRODUCTAMOUNT=").append(money_)
            .append("&ATTACHAMOUNT=")
            .append("0.00").append("&ATTACH=").append(attach_order_id).append("&DIVDETAILS=")
            .append("")
            .append("&ACCOUNTID=").append("").append("&CUSTOMERID=").append(phone)
            .append("&USERIP=").append("")
            .append("&BUSITYPE=").append("04").append("&SWTICHACC=").append("true")
            .append("&SUBJECT=")
            .append(body);

        // 返回数据
        String params = paramsBuffer.toString();
        transport = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        transport.setData(params);
        return transport;
    }

    /**
     * 翼支付预支付回调
     *
     * @param request
     */
    @RequestMapping("bestpay/notify")
    public synchronized void bestPayNotify(HttpServletRequest request,
        HttpServletResponse response) {
        try {
            // 准备
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();

            // 获取回调数据，注释部分为没有使用的部分数据，其所代表的意义详见翼支付APP文档
            String UPTRANSEQ = request.getParameter("UPTRANSEQ");
            String MERCHANTID = request.getParameter("MERCHANTID");
            String TRANDATE = request.getParameter("TRANDATE");
            String RETNCODE = request.getParameter("RETNCODE");
            String RETNINFO = request.getParameter("RETNINFO");
            // String ORDERREQTRANSEQ = request.getParameter("ORDERREQTRANSEQ");
            String ORDERSEQ = request.getParameter("ORDERSEQ");
            String ORDERAMOUNT = request.getParameter("ORDERAMOUNT");
            // String PRODUCTAMOUNT = request.getParameter("PRODUCTAMOUNT");
            // String ATTACHAMOUNT = request.getParameter("ATTACHAMOUNT");
            // String CURTYPE = request.getParameter("CURTYPE");
            // String ENCODETYPE = request.getParameter("ENCODETYPE");
            // String BANKID = request.getParameter("BANKID");
            String ATTACH = request.getParameter("ATTACH");
            // String UPREQTRANSEQ = request.getParameter("UPREQTRANSEQ");
            // String UPBANKTRANSEQ = request.getParameter("UPBANKTRANSEQ");
            // String PRODUCTNO = request.getParameter("PRODUCTNO");
            String SIGN = request.getParameter("SIGN");

            // 验证签名
            Setting setting = settingUtils.get();
            String key = setting.getMerKey();
            String signStr =
                "UPTRANSEQ=" + UPTRANSEQ + "&MERCHANTID=" + MERCHANTID + "&ORDERSEQ=" + ORDERSEQ
                    + "&ORDERAMOUNT=" + ORDERAMOUNT + "&RETNCODE=" + RETNCODE + "&RETNINFO="
                    + RETNINFO + "&TRANDATE="
                    + TRANDATE + "&KEY=" + key;
            String localSign = CryptTool.md5Digest(signStr);

            // 验签失败
            if (!localSign.equals(SIGN)) {
                out.write("UPTRANSEQ_" + UPTRANSEQ);
                logger.info("支付回调，验签失败！");
                return;
            }

            // 验签成功，看是否支付成功("0000为成功，其他均为失败")
            if (RETNCODE.equals("0000")) {

                // 获取订单号并获取临时订单
                Long orderId = Long.valueOf(ATTACH.split("_")[2]); // 商户订单号 取数组下表第三位
                OrderTemp temp = orderTempService.findOne(orderId); // 临时订单

                if (null == temp) {
                    logger.info("该临时订单不存在");
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                // 判断预支付是否成功付款
                if (temp.isTreatment()) {
                    logger.info("临时订单已完成");
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                // 将订单相关信息set进去
                Order order = new Order();
                if (null != temp.getOrderNoRenBao() && null != temp.getCuponNoRenBao()) {
                    order.setOrderNoRenBao(temp.getOrderNoRenBao());
                    order.setCuponNoRenBao(temp.getCuponNoRenBao());
                }
                order.setClientId(temp.getClientId());
                order.setClientName(temp.getClientName());
                order.setClientPhone(temp.getClientPhone());
                order.setUserPhone(temp.getUserPhone());
                order.setFromPlace(temp.getFromPlace());
                order.setClientLatitude(temp.getClientLatitude());
                order.setClientLongitude(temp.getClientLongitude());
                order.setToPlace(temp.getToPlace());
                order.setToPlaceLatitude(temp.getToPlaceLatitude());
                order.setToPlaceLongitude(temp.getToPlaceLongitude());
                order.setServerTime(temp.getServerTime());
                order.setOrderCarType(OrderCarType.daijia);
                order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);
                order.setBestpayMoney(temp.getPrepayCash());
                order.setFromSource(Order.ORDER_TYPE_APP);
                order.setOrderType(Order.ORDER_TYPE_APP);

                // 判断优惠券不为空的话，查询到当前优惠券的id
                Coupon coupon = null;
                if (null != temp.getCouponId()) {
                    coupon = couponService.findOne(temp.getCouponId());
                }

                // 优惠卷+翼支付
                if (null != coupon) {
                    order.setPrePayTypeDetail(Order.PayTypeDetails.coupon_bestpay);

                } else {
                    // 翼支付
                    order.setPrePayTypeDetail(Order.PayTypeDetails.bestpay);
                }

                Long[] couponIds = null;
                if (null != coupon) {
                    couponIds = new Long[1];
                    couponIds[0] = coupon.getId();
                }

                // 创建订单
                Result<Order> result = orderService
                    .create(order, 1, couponIds, temp.getClientLongitude(),
                        temp.getClientLatitude(), temp.getCompanyId(), null, null,
                        temp.getShouldCash());

                if (!result.isSuccess()) {
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                // 更新为交易成功
                orderTempService.updateTreatment(temp.getId());

                // 客户消费记录
                Order newOrder = result.getData().get(0);

                // 乘客
                Passenger passenger = memberService.findOnePassenger(temp.getClientId());

                // 拼接乘客需要支付的数据
                String payMemo = "订单【" + newOrder.getOrderNumber() + "】" + "预付费使用翼支付支付"
                    + temp.getPrepayCash().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "元。";

                // 这里是判断如果有优惠券的话，则在支付的数据后面进行拼接 优惠券分为多少元或者打几折的
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getMoney() + "元优惠券。";

                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        payMemo += "并且使用了" + coupon.getCouponRule().getDiscount() + "折优惠券。";
                    }
                }

                // 判断是个人还是企业，这里是个人
                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    memberService.money(passenger, null, temp.getPrepayCash().negate(), payMemo,
                        PassengerAccount.OPERATING_SYS, PassengerAccount.PayType.PAYTYPE_BESTPAY,
                        newOrder.getId(),
                        newOrder.getOrderNumber(), PassengerAccount.ORDER_TYPE_DAIJIA, null, false,
                        false);

                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    // 否则如果乘客是企业的话
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id()); // 先根据id查询出企业
                    // 判断如果企业不为空的话，查询企业支付费用
                    if (null != enterprise) {
                        memberService
                            .moneyEnterprise(enterprise, temp.getPrepayCash().negate(), payMemo,
                                PassengerAccount.OPERATING_SYS,
                                PassengerAccount.PayType.PAYTYPE_BESTPAY,
                                newOrder.getId(), newOrder.getOrderNumber(),
                                PassengerAccount.ORDER_TYPE_DAIJIA, null,
                                false, false);
                    }
                }

                // 这里做订单遍历
                for (Order order2 : result.getData()) {
                    OrderCreateEvent event = new OrderCreateEvent(order2); // 创建订单对象
                    // 事件广播器：ApplicationEventMulticaster，将Springpublish的事件广播给所有的监听器。
                    applicationEventMulticaster.multicastEvent(event);
                    OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order2);
                    applicationEventMulticaster.multicastEvent(orderRecordEvent);
                }

                OrderNewRushEvent newRushEvent = new OrderNewRushEvent(result.getData());
                applicationEventMulticaster.multicastEvent(newRushEvent);
            }

            out.write("UPTRANSEQ_" + UPTRANSEQ);
        } catch (Exception e) {
            // 异常不返回，以便不丢失支付数据
            e.printStackTrace();
        }
    }

    /**
     * 代驾付费结算
     *
     * @param request 请求对象
     * @param orderId 订单号
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "bestpay/afterpay")
    public synchronized ResultTransport bestPayByAfterPay(HttpServletRequest request, Long orderId)
        throws Exception {

        ResultTransport transport = null;

        // 参数校验
        if (null == orderId || orderId.equals(0)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        // 获取订单
        Order order = orderService.findOne(orderId);

        if (order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_BUSY)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (!order.isTreatment()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_CONFIRM);
        }

        BigDecimal money = BigDecimal.ZERO;
        if (null != order.getPrePayTypeDetail()) {

            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                money = order.getRealCash().subtract(order.getCouponMoney());
            } else {
                money = order.getRealCash().subtract(order.getShouldCash());
            }

        } else {
            money = order.getRealCash();
        }

        PayRecordOrder payRecordOrder = new PayRecordOrder();
        payRecordOrder.setMoney(money);
        payRecordOrder.setOrderId(orderId);
        payRecordOrder.setPayRecordTypeOrder(PayRecordTypeOrder.bestpay);
        payRecordOrder.setTreatment(false);
        payRecordOrderService.insertRecord(payRecordOrder);

        // 获取系统设置
        Setting setting = settingUtils.get();
        String callBackUrl = setting.getWebUrl() + "/api/daijia/bestpay/afternotify";
        String createUrl = "https://webpaywg.bestpay.com.cn/order.action";

        // 获取商户信息
        String mch_id = setting.getMerchantId();
        String mch_key = setting.getMerKey();
        String mch_pwd = setting.getMchPwd();
        String riskInfo = setting.getRiskcontrolinfo();
        String attach_order_id =
            "dj_af_" + payRecordOrder.getId() + "_" + order.getId(); // 商户订单号,这里作为附加信息，因为订单不能个包含特殊字符
        String body = "代驾结算付费-" + order.getOrderNumber();

        // 使用随机数来作为订单流水号
        String currTime = TenpayUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length()); // 8位日期
        String strRandom = TenpayUtil.buildRandom(6) + ""; // 四位随机数
        String strReq = strTime + strRandom; // 10位序列号,可以自行调整

        // 格式化金额0.00
        DecimalFormat myformat = new java.text.DecimalFormat("0.00");
        String money_ = myformat.format(money);
        String phone = order.getClientPhone();

        // 订单模型
        String total_fee = String.valueOf(money.multiply(new BigDecimal(100)).intValue()); // 元转分
        BestPayOrderModel orderModel = new BestPayOrderModel();
        orderModel.setATTACH(attach_order_id);
        orderModel.setCITYCODE("");
        orderModel.setDIVDETAILS("");
        orderModel.setENCODE("");
        orderModel.setENCODETYPE("1");
        orderModel.setKEY(mch_key);
        orderModel.setLOGINNO("");
        orderModel.setMERCHANTID(mch_id);
        orderModel.setORDERAMT(total_fee); // 分
        orderModel.setORDERCCY("RMB");
        orderModel.setORDERREQTIME(currTime);
        orderModel.setORDERREQTRANSEQ(strReq);
        orderModel.setORDERSEQ(strReq);
        orderModel.setPRODUCTDESC(body);
        orderModel.setPRODUCTID("04");
        orderModel.setPROVINCECODE("");
        orderModel.setRISKCONTROLINFO(riskInfo);
        orderModel.setSERVICECODE("05");
        orderModel.setSESSIONKEY("");
        orderModel.setSUBMERCHANTID("");
        orderModel.setTRANSCODE("01");
        boolean rs = BestPayCreateOrder.createByApp(createUrl, orderModel);

        // 下单失败
        if (!rs) {
            return ResultTransport.getErrorBy(ErrorConstantV4.BESTPAY_APP_CREATE_ORDER_ERR);
        }

        // 签名参数
        StringBuffer md5Buffer = new StringBuffer();
        md5Buffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
            .append(mch_id)
            .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
            .append("&BACKMERCHANTURL=").append(callBackUrl).append("&ORDERSEQ=").append(strReq)
            .append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=").append(currTime)
            .append("&ORDERVALIDITYTIME=").append("").append("&CURTYPE=").append("RMB")
            .append("&ORDERAMOUNT=")
            .append(money_).append("&SUBJECT=").append(body).append("&PRODUCTID=").append("04")
            .append("&PRODUCTDESC=").append(body).append("&CUSTOMERID=").append(phone)
            .append("&SWTICHACC=")
            .append("true").append("&KEY=").append(mch_key);

        // 签名
        logger.info("MAC(MD5)--before--String：" + md5Buffer.toString());
        String sign = CryptTool.md5Digest(md5Buffer.toString());
        logger.info("MAC(MD5)--after--String:" + sign);

        // 拼接返回数据串
        StringBuffer paramsBuffer = new StringBuffer();
        paramsBuffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
            .append(mch_id)
            // 签约商户号
            .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
            .append("&BACKMERCHANTURL=").append(callBackUrl).append("&SIGNTYPE=").append("MD5")
            .append("&SIGN=")
            .append(sign).append("&ORDERSEQ=").append(strReq).append("&ORDERREQTRANSEQ=")
            .append(strReq)
            .append("&ORDERTIME=").append(currTime).append("&ORDERVALIDITYTIME=").append("")
            .append("&ORDERAMOUNT=")
            .append(money_).append("&CURTYPE=").append("RMB").append("&PRODUCTID=").append("04")
            .append("&PRODUCTDESC=").append(body).append("&PRODUCTAMOUNT=").append(money_)
            .append("&ATTACHAMOUNT=")
            .append("0.00").append("&ATTACH=").append(attach_order_id).append("&DIVDETAILS=")
            .append("")
            .append("&ACCOUNTID=").append("").append("&CUSTOMERID=").append(phone)
            .append("&USERIP=").append("")
            .append("&BUSITYPE=").append("04").append("&SWTICHACC=").append("true")
            .append("&SUBJECT=")
            .append(body);

        // 返回数据
        String params = paramsBuffer.toString();
        transport = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        transport.setData(params);
        return transport;
    }

    /**
     * 代驾支付结算
     *
     * @param request  请求对象
     * @param response 响应对象
     */
    @RequestMapping("bestpay/afternotify")
    public synchronized void bestPayByAfterPayNotify(HttpServletRequest request,
        HttpServletResponse response) {
        try {
            // 准备
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();

            // 获取回调数据，注释部分为没有使用的部分数据，其所代表的意义详见翼支付APP文档
            String UPTRANSEQ = request.getParameter("UPTRANSEQ");
            String MERCHANTID = request.getParameter("MERCHANTID");
            String TRANDATE = request.getParameter("TRANDATE");
            String RETNCODE = request.getParameter("RETNCODE");
            String RETNINFO = request.getParameter("RETNINFO");
            // String ORDERREQTRANSEQ = request.getParameter("ORDERREQTRANSEQ");
            String ORDERSEQ = request.getParameter("ORDERSEQ");
            String ORDERAMOUNT = request.getParameter("ORDERAMOUNT");
            // String PRODUCTAMOUNT = request.getParameter("PRODUCTAMOUNT");
            // String ATTACHAMOUNT = request.getParameter("ATTACHAMOUNT");
            // String CURTYPE = request.getParameter("CURTYPE");
            // String ENCODETYPE = request.getParameter("ENCODETYPE");
            // String BANKID = request.getParameter("BANKID");
            String ATTACH = request.getParameter("ATTACH");
            // String UPREQTRANSEQ = request.getParameter("UPREQTRANSEQ");
            // String UPBANKTRANSEQ = request.getParameter("UPBANKTRANSEQ");
            // String PRODUCTNO = request.getParameter("PRODUCTNO");
            String SIGN = request.getParameter("SIGN");

            // 验证签名
            Setting setting = settingUtils.get();
            String key = setting.getMerKey();
            String signStr =
                "UPTRANSEQ=" + UPTRANSEQ + "&MERCHANTID=" + MERCHANTID + "&ORDERSEQ=" + ORDERSEQ
                    + "&ORDERAMOUNT=" + ORDERAMOUNT + "&RETNCODE=" + RETNCODE + "&RETNINFO="
                    + RETNINFO + "&TRANDATE="
                    + TRANDATE + "&KEY=" + key;
            String localSign = CryptTool.md5Digest(signStr);

            // 验签失败
            if (!localSign.equals(SIGN)) {
                out.write("UPTRANSEQ_" + UPTRANSEQ);
                logger.info("支付回调，验签失败！");
                return;
            }

            // 验签成功，看是否支付成功("0000为成功，其他均为失败")
            if (RETNCODE.equals("0000")) {

                // 获取支付记录订单号，并获取该记录
                Long recordId = Long.valueOf(ATTACH.split("_")[2]);
                PayRecordOrder payRecordOrder = payRecordOrderService.findOne(recordId);

                if (null == payRecordOrder) {
                    logger.info("支付记录不存在！");
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                if (payRecordOrder.isTreatment()) {
                    logger.info("支付记录已完成！");
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                // 根据记录中的订单号获取订单
                Order order = orderService.findOne(payRecordOrder.getOrderId());
                if (order.getStatus().equals(Order.ORDER_STATUS_FINISHED)
                    || order.getStatus().equals(Order.ORDER_STATUS_BAODAN)) {
                    logger.info("订单已经结算或订单已经报单");
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

                // 获取乘客司机和所有的订单任务
                Passenger passenger = memberService.findOnePassenger(order.getClientId());
                Driver driver = driverService.findOne(order.getDriverId());
                Result<Order> result = orderService
                    .completeTaskNewV3(order, passenger, driver, "onlinePay", "bestpay",
                        null, false);

                if (result.isSuccess()) {

                    // 完成工单事件
                    ReactorVo rVo = new ReactorVo();
                    rVo.setDriver(driver);
                    rVo.setOrder(order);

                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver,
                        order.getId(), "daijia");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);

                    OrderFinishEvent finishEvent = new OrderFinishEvent(rVo);
                    applicationEventMulticaster.multicastEvent(finishEvent);

                    if (null != passenger) {
                        ReactorVo rVo2 = new ReactorVo();
                        rVo2.setOrderChannelName(order.getOrderType());
                        rVo2.setOrderType(OrderType.daijia);
                        rVo2.setPassenger(passenger);
                        rVo2.setActivityEvent(ActivityEvent.orderCompleteTimes);
                        ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo2);
                        applicationEventMulticaster.multicastEvent(activityCheckEvent);

                        MemberRebateEvent memberRebateEvent = new MemberRebateEvent(passenger,
                            order,
                            order.getRealCash(), 1);
                        applicationEventMulticaster.multicastEvent(memberRebateEvent);
                    }

                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;

                } else {
                    out.write("UPTRANSEQ_" + UPTRANSEQ);
                    return;
                }

            }
            out.write("UPTRANSEQ_" + UPTRANSEQ);
        } catch (Exception e) {
            // 异常不返回，以便不丢失支付数据
            e.printStackTrace();
        }
    }
}
